gpt4 book ai didi

c++ - 如果我碰巧注意到它已过期,我应该在 weak_ptr 上调用 reset 吗?

转载 作者:可可西里 更新时间:2023-11-01 16:15:05 24 4
gpt4 key购买 nike

我收藏了 Creature使用 std::make_shared 在我的应用程序的一部分中创建和拥有的对象和 std::shared_ptr .

我还跟踪了零个或一个的选择 CreatureWorld使用 std::weak_ptr<Creature> 的对象.

void World::SetSelection(const std::shared_ptr<Creature>& creature) {
selection = creature;
}

std::shared_ptr<Creature> World::GetSelection() const {
return selection.lock();
}

GetSelection的来电者负责检查指针是否为空。如果是,则表示当前没有选择。

This all works perfectly to my liking: when the selected Creature死于自然原因(在申请的其他地方),GetSelection开始返回 nullptr再次好像什么都没有被选择。

但是在那种情况下 World::selection成员仍然指向 std::shared_ptr的控制 block 。这可能很大,因为我使用 std::make_shared创建我的 Creature对象(我意识到 Creature 对象在正确的时间被正确销毁,但它的内存仍然被分配)。我正在考虑更改 GetSelection对此:

std::shared_ptr<Creature> World::GetSelection() {
const auto ret = selection.lock();
if (!ret)
selection.reset();

return ret;
}

这会在我发现不再需要内存时立即释放内存。恼人的是,这个版本的GetSelection不能是 const .

我的问题:

  1. 哪个版本GetSelection在这种情况下会被认为是最佳实践吗?

  2. 如果在模板代码中发生类似的事情,答案是否会改变,其中 sizeof(T)是未知的,可能是巨大的?或者在 C++14 中 std::make_shared<T[]>可以参与吗?

  3. 如果第二个版本总是最好的,那么 std::weak_ptr<T>::expired 的基本原理是什么?和 lock自己不做?

最佳答案

首先应该注意的是,std::make_shared 的放置策略是可选的,即标准不强制执行此优化。这是一个非约束性要求,这意味着完全符合要求的实现可能会选择放弃它。

回答您的问题:

  1. 鉴于您似乎只有一个选择(因此您并没有通过保留许多这样的控制 block 来增加内存使用量),我主张保持简单。内存是瓶颈吗?这对我来说是微优化。您应该编写更简单的代码,您可以在其中应用 const,然后在需要时返回并稍后进行优化。

  2. 答案不会无条件地改变,它会根据问题域和你的瓶颈是什么而改变。如果您正在分配一个“巨大”的对象(比如一百千字节),并且该对象的空间在一个相对未使用的控制 block 中四处游荡,直到被替换,这可能不是您的瓶颈,而且可能不值得编写更多代码(本质上更容易出错、难以维护和破译)来“解决”。

  3. 由于std::weak_ptr::lockstd::weak_ptr::expiredconst,在解释下const 对于 C++11,它们必须是线程安全的。因此,给定一些 std::weak_ptr,同时调用 lock()expired() 的任意组合必须是安全的。在引擎盖下,std::weak_ptr 存储一个指向控制 block 的指针,它通过它查看检查/增量/等。原子计数器来确定对象是否已经过期,或者看它是否可以获取锁。如果您想在 std::weak_ptr 内部实现优化,您必须以某种方式检查控制 block 的状态,然后在指针过期时自动删除指向控制 block 的指针。这会在每次访问 std::weak_ptr 时产生开销(即使这可以简单地用原子完成,它仍然会有开销),所有这些都是为了一个小的优化。

关于c++ - 如果我碰巧注意到它已过期,我应该在 weak_ptr 上调用 reset 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25274871/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com