来自boost :: shared_ptr的增强文档:
因为实现使用引用计数,循环 shared_ptr实例将不会被回收。例如,如果main() 将shared_ptr保存到A,直接或间接持有 shared_ptr回到A,A的使用计数将是2.毁灭 原始的shared_ptr将使用一个悬空,使用次数为1 weak_ptr“打破周期。”
我无法理解这一段,您是否能提供这种情况的最低范例并解释其后果。
答案 0 :(得分:4)
智能指针如何工作?它们记住指向对象的智能指针的count
,当新的共享指针控制对象时增加此count
,如果共享指针失去对{1}}的控制权,则减少count
对象
假设您有一个班级:
class A{
public:
A(){std::cout << "Object created" << std::endl;}
~A(){std::cout << "Object destroyed" << std::endl;}
void setSibling(boost::shared_ptr<A> &sibling){
m_sibling = sibling;
}
private:
boots::shared_ptr<A> m_sibling;
};
和foo():
void foo(){
//count increases from 0 to 1 (ptr take control on instance of A)
boost::shared_ptr<A> ptr(new A);
//count increases from 1 to 2 (m_sibling take control on instanse of A)
ptr->setSibling(ptr);
//count decreases from 2 to 1
//(ptr is destroyed and lose control on instance of A)
return;
}
当调用~A()时,m_sibling将失去控制,但只有当所有共享指针都将丢失控件时才会调用~A()。 因此,在调用foo之后,您无法访问该A实例。但是计数为1且共享指针不会删除该对象,因此您有内存和资源泄漏。
请参阅boost中weak_ptr
的文档,了解如何将其与shared_ptr
一起使用。
简而言之:弱指针就像共享指针,但不会增加count
。如果你有一个从shared_ptr
创建的weak_ptr实例到被销毁的对象,如果你试图访问原始指针,weak_prt实例将抛出异常(不会发生段错误)。 boost文档中有一个示例如何使用weak_prt
方法正确使用weak_ptr::lock()
。
答案 1 :(得分:1)
想象一下宝藏
你的朋友拿了一个胸口并放入一些金币。他还制作了一张地图
这是一个带有一个条款的神奇地图:如果你刻录了地图的最新副本,那么宝藏和黄金就会消失
你的朋友将地图放在金色的胸前,为你制作第二张地图,并用第一张地图封闭胸部
他给你第二份地图副本并随宝藏一起消失
问题是:如果你刻录你的地图会发生什么?
答案:没什么,宝藏还在某处。
为什么呢?因为地图的最新副本还在胸前!
答案 2 :(得分:0)
以下是一个示例(请注意,此处永远不会调用~A
):
#include <boost/shared_ptr.hpp>
#include <iostream>
using boost::shared_ptr;
struct A
{
~A()
{
std::cout << "~A()" << std::endl;
}
void set_shared_ptr(const shared_ptr<A> &p)
{
p_ = p;
}
shared_ptr<A> p_;
};
int main()
{
shared_ptr<A> q(new A);
q->set_shared_ptr(q);
q.reset();
}
答案 3 :(得分:-1)
因为实现使用引用计数,循环 不会回收shared_ptr实例。
你写道:
我无法理解这一段
那很好;这是因为你很聪明。该段没有任何意义。如果你认为你得到它,那就意味着你没有。
循环无法回收,好吧,因为存在循环依赖性!循环的其余部分在回收之前不能回收循环的任何部分,因此您必须将每个对象都销毁在它的破坏开始之前。如果你有循环依赖,它是你程序破碎设计的一部分。不要试图责备智能指针(或引用计数)。
基本依赖性问题的任何部分都与智能指针的实现细节无关; 它是由拥有智能指针的定义引起的:拥有的对象在(最后)拥有指针的析构函数开始运行之前不会被销毁。
当然,对于std::unique_ptr
这样的独家所有权智能指针来说也是如此,它甚至没有参考计数!
将weak_ptr用于&#34;中断周期。&#34;
唐&#39;吨。避免循环。你不能打破&#34;打破&#34;一个循环。没有&#34;打破&#34;一个周期。
Boost的文档比这里更糟糕。这很危险。它在这样的级别上混合了不变量和实现,它表明对智能指针的语义的理解非常糟糕。
它讲述了虚假信息和反模式自我复制的能力!