[英]Role of weak_ptr in shared_ptr
我理解shared_ptr如何工作,除了weak_ptr的角色。 我理解它在那里检测循环引用时引用计数不为零,但除此之外,我不明白它究竟是如何做到的。 它有什么作用?
另请参见: std :: weak_ptr何时有用? 为什么以及weak_ptr如何工作? 如何。
我将举例说明我如何使用它,虽然我掀起的示例代码有点令人费解,所以请耐心等待:
#include <vector>
#include <memory>
#include <ostream>
int main()
{
// Fill container with values 1-50. This container OWNS these values.
std::vector<std::shared_ptr<int>> owning_container;
for(int i = 1; i <= 50; ++i)
{
owning_container.emplace_back(std::make_shared<int>(i));
}
// Create a sepearate container that references all owned values that are multiples of 5.
std::vector<std::weak_ptr<int>> referencing_container;
for(std::shared_ptr<int> const& i : owning_container)
{
if((*i) % 5 == 0)
{
// Make weak_ptr that references shared_ptr
referencing_container.emplace_back(i);
}
}
// Go through the owned values and delete all that are multiples of 10.
for(auto it = owning_container.begin(); it != owning_container.end();)
{
std::shared_ptr<int> const& i = *it;
if(*i % 10 == 0)
{
it = owning_container.erase(it);
}
else
{
++it;
}
}
// Now go through the referencing container and print out all values.
// If we were dealing with raw pointers in both containers here we would access deleted memory,
// since some of the the actual resources (in owning_container) that referencing_container
// references have been removed.
for(std::weak_ptr<int> const& i_ref : referencing_container)
{
// Check if the shared resource still exists before using it (purpose of weak_ptr)
std::shared_ptr<int> i = i_ref.lock();
if(i)
{
std::cout << *i << std::endl;
}
}
return 0;
}
在这里,我们有一个包含一些共享资源的容器 - 在这种情况下为 - ( shared_ptr
),另一个容器需要引用( weak_ptr
)。 引用不拥有资源,只需要能够访问它( 如果存在) 。 为了判断被引用的资源是否仍然存在,我们使用weak_ptr::lock()
将weak_ptr
转换为shared_ptr
。 那些仍然存在的资源将具有lock()
返回的有效shared_ptr
。 那些不再存在的将返回null shared_ptr
。 shared_ptr
有一个operator bool()
,我们可以在尝试使用它之前检查它是否为null。
如果你制作的游戏中游戏中的每个对象都由game_object
代表,那么一个不太复杂的场景可能就是game_object
。 假设你有一种寻求敌人的逻辑,这需要一个目标game_object
来寻求。 使用上面的方法,你可以让敌人抓住一个weak_ptr<game_object>
。 它不拥有这个game_object
。 如果其他东西杀死其目标,其目标应该死亡; 如果敌人持有一个shared_ptr
而不会陷入某种不稳定状态。 这样,如果敌人的目标仍然存活(可以通过锁定weak_ptr
来检查),它可以执行搜索逻辑; 否则它可以找到新的目标。 game_object
的“所有者”可能是某种类型的game_world
类 - 这将有一个shared_ptr<game_object>
的容器。 当敌人需要一个新目标时,它可以搜索这个容器并从game_world
的shared_ptr
创建它的weak_ptr
。
弱指针不声明资源的所有权,而只是引用它。 因此,它们不允许您以任何方式对资源进行操作,除了再次声明所有权(使用weak_ptr::lock()
方法)。 恕我直言,这种行为所需的最常见的现实生活情况是循环依赖和(较不频繁)缓存。
使用共享指针进行的循环依赖只是事实上的内存泄漏,因为指针的相互引用计数永远不会小于1:如果没有别的东西拥有A,那么B仍然会这样做,反之亦然。 弱指针不能“检测”这种情况。 只是通过打破所有权循环,它不会让麻烦进入。 您可能仍然通过锁定弱指针来“连接链的末端”,但是您可能通过弱指针获得的共享指针都不会持久存在。
缓存的问题是,缓存通常不应该影响缓存内容的生命周期,它不是缓存的职责。 但是,如果缓存将保存共享指针,那么您将无法终止缓存对象的生命周期而无需与缓存进行通信,这通常很不方便。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.