精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容
weak_ptr是C++17智能指针中提到的最后一个,前面提到的是share_ptr,所以和share_ptr结合使用就是weak_ptr的用途,解决share_ptr强耦合带来的问题,也就是循环引用问题。
weak是弱的意思,但按弱理解,不太好理解,用虚指虚代来理解就好理解了,把weak_ptr理解为虚代其它指针,自己不负责,就明白意思了。
下面是weak_ptr解决循环引用问题的代码示例:
class B;
class A
{
public:
A( ) : m_a(5) { };
~A( )
{
cout<<" A is destroyed"<<endl;
}
void PrintSpB( );
weak_ptr<B> m_sptrB;
int m_a;
};
class B
{
public:
B( ) : m_b(10) { };
~B( )
{
cout<<" B is destroyed"<<endl;
}
weak_ptr<A> m_sptrA;
int m_b;
};
void A::PrintSpB( )
{
if( !m_sptrB.expired() )
{
cout<< m_sptrB.lock( )->m_b<<endl;
}
}
void main( )
{
shared_ptr<B> sptrB( new B );
shared_ptr<A> sptrA( new A );
sptrB->m_sptrA = sptrA;
sptrA->m_sptrB = sptrB;
sptrA->PrintSpB( );
}
把类内部的成员的类型从share_ptr改成weak_ptr就不会有循环引用问题了。expired函数功能是判断weak_ptr的内部内存区有效与否,是否还可用。返回假可用。
循环引用的另外一个场景:具有三个元素的循环的链接列表有一个头节点 N0;该节点保留有一个拥有下一个节点 N1 的 shared_ptr 对象;该节点保留有一个拥有下一个节点 N2 的 shared_ptr 对象;反过来,该节点保留有一个拥有头节点 N0 的 shared_ptr 对象,由此形成闭合循环。 在这种情况下,引用计数从不变为零,并且从不释放循环中的节点。 若要消除循环,最后一个节点 N2 应保留指向 N0 的 weak_ptr 对象,而不是 shared_ptr 对象。 由于 weak_ptr 对象不拥有 N0,因此不会影响 N0 的引用计数,并且销毁该程序对头节点的最后一个引用时,也将销毁列表中的节点。
大家有时间可以自己编写代码实现下。