精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容
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 的引用计数,并且销毁该程序对头节点的最后一个引用时,也将销毁列表中的节点。
大家有时间可以自己编写代码实现下。