智能指针有什么不足之处?
举个循环引用的例子
-----------------------------------------------------------------------------------------------------------------------
class
B;
class
A
{
public
:
shared_ptr<B> m_b;
};
class
B
{
public
:
shared_ptr<A> m_a;
};
int
main()
{
while
(
true
)
{
shared_ptr<A> a(
new
A);
//new出来的A的引用计数此时为1
shared_ptr<B> b(
new
B);
//new出来的B的引用计数此时为1
a->m_b = b;
//B的引用计数增加为2
b->m_a = a;
//A的引用计数增加为2
}
//b先出作用域,B的引用计数减少为1,不为0,所以堆上的B空间没有被释放,且B持有的A也没有机会被析构,A的引用计数也完全没减少
//a后出作用域,同理A的引用计数减少为1,不为0,所以堆上A的空间也没有被释放
}
如此一来,A和B都互相指着对方吼,“放开我的引用!“,“你先发我的我就放你的!”,于是悲剧发生了。
所以在使用基于引用计数的智能指针时,要特别小心循环引用带来的内存泄漏,循环引用不只是两方的情况,只要引用链成环都会出现问题。当然循环引用本身就说明设计上可能存在一些问题,如果特殊原因不得不使用循环引用,那可以让引用链上的一方持用普通指针(或弱智能指针weak_ptr)即可。