weak_ptr基本使用方法
- weak_ptr只有shared_ptr观测权没有使用权,不增加shared_ptr引用计数
- 如果要使用weak_ptr指向对象的功能,不能直接使用而应先用
weak_ptr::lock()
创建shared_ptr对象 - weak_ptr用来防止shared_ptr的循环引用问题
class A{
public:
A(){cout << "A constructed\n";}
~A(){cout << "A deconstructed.\n";}
void work(){cout <<"work is called\n";}
};
int main(){
shared_ptr<A> ptr1(new A());
weak_ptr<A> ptr2 = ptr1;
cout << ptr1.use_count()<< endl;
cout << ptr2.use_count() << endl;//weak_ptr不增加shared_ptr引用计数
{
//使用weak_ptr必须先用weak_ptr::lock创建shared_ptr对象
if(auto ptr3 = ptr2.lock()){
ptr3->work();
}
else
cout <<"weak_ptr expired\n";
}
return 0;
}
weak_ptr的使用惯例
if(auto ptr2 = wptr.lock()){
//ptr2 is a new shared_ptr
ptr2->work();
}
weak_ptr作用避免循环引用
这里错误的设计 类A包含一个shared_ptr<B>
,类B包含shared_ptr<A>
,彼此为相互的shared_ptr赋值。
using namespace std;
//前置声明 因为定义A会用到B
class A;
class B;
class A{
shared_ptr<B> ptrB;
public:
void setB(shared_ptr<B> & p){ ptrB = p;}
A(){cout << "A constructed\n";}
~A(){cout << "A deconstructed.\n";}
void workA(){cout <<"work A is called\n";}
};
class B{
shared_ptr<A> ptrA;
public:
void setA(shared_ptr<A> & p){ ptrA = p;}
B(){cout << "B constructed\n";}
~B(){cout << "B deconstructed.\n";}
void workB(){cout <<"work B is called\n";}
};
int main(){
weak_ptr<A> observerA;
weak_ptr<B> observerB;
{
shared_ptr<A> a(new A);
shared_ptr<B> b(new B);
a->setB(b);
b->setA(a);
cout <<"a use_count()" << a.use_count() << endl;
cout <<"b. use_count()" << b.use_count() << endl;
//weak_ptr不增加引用计数
observerA = a;
observerB = b;
}
cout << "observerA.use_count()"<< observerA.use_count() << endl;
cout << "observerB.use_count()"<<observerB.use_count() << endl;
return 0;
}
输出 最后A和B都没被正确释放
A constructed
B constructed
a use_count()2
b. use_count()2
observerA.use_count()1
observerB.use_count()1
如果让类A包含一个weak_ptr
class A{
weak_ptr<B> ptrB;
那么得到的结果为 两个类都被正确释放
A constructed
B constructed
a use_count()2
b. use_count()1
B deconstructed.
A deconstructed.
observerA.use_count()0
observerB.use_count()0