条款1:不要把一个原生指针给多个shared_ptr管理
int* ptr = new int;
shared_ptr<int> p1(ptr);
shared_ptr<int> p2(ptr); //logic error
ptr对象被删除了2次
这种问题比喻成“二龙治水”,在原生指针中也同样可能发生。
条款2:不要把this指针给shared_ptr
class Test{
public:
void Do(){ m_sp = shared_ptr<Test>(this); }
private:
shared_ptr<Test> m_member_sp;
};
Test* t = new Test;
shared_ptr<Test> local_sp(t);
p->Do();
发生什么事呢,t对象被删除了2次!
t对象给了local_sp管理,然后在m_sp = shared_ptr<Test>(this)这句里又请了一尊神来管理t。
这就发生了条款1里“二龙治水”错误。
条款3:shared_ptr作为被保护的对象的成员时,小心因循环引用造成无法释放资源。
对象需要相互协作,对象A需要知道对象B的地址,这样才能给对象B发消息(或调用其方法)。
设计模式中有大量例子,一个对象中有其他对象的指针。现在把原生指针替换为shared_ptr.
假设a对象中含有一个shared_ptr<B>指向b对象;假设b对象中含有一个shared_ptr<A>指向a对象
并且a,b对象都是堆中分配的。很轻易就能与他们失去最后联系。
考虑某个shared_ptr<A> local_a;是我们能最后一个看到a对象的共享智能指针,其use_count==2,
因为对象b中持有a的指针。所以当local_a说再见时,local_a只是把a对象的use_count改成1。
同理b对象。然后我们再也看不到a,b的影子了,他们就静静的躺在堆里,成为断线的风筝。
解决方案是:Use weak_ptr to "break cycles."(boost文档里写的)或者显示的清理
条款4:不要在函数实参里创建shared_ptr
function ( shared_ptr<int>(new int), g( ) ); //有缺陷
可能的过程是先new int,然后调g( ),g( )发生异常,shared_ptr<int>没有创建,int内存泄露
shared_ptr<int> p(new int());