C++智能指针之weak_ptr

weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象. 进行该对象的内存管理的是那个强引用的 shared_ptr. weak_ptr只是提供了对管理对象的一个访问手段。

weak_ptr是用来协助 shared_ptr 解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。它是对对象的一种弱引用,不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr。

#include 

using namespace std;
class B;
class A
{
public:
	shared_ptr pb_;
	~A()
	{
		cout << "A delete\n";
	}
};
class B
{
public:
	shared_ptr pa_;
	~B()
	{
		cout << "B delete\n";
	}
};
void fun()
{
	shared_ptr pb(new B());
	shared_ptr pa(new A());
	pb->pa_ = pa;
	pa->pb_ = pb;
	cout << pb.use_count() << endl;
	cout << pa.use_count() << endl;
}
int main()
{
	fun();
	system("pause");
	return 0;
}

结果:

我们发现A和B的析构函数均没有被调用,修改代码:将类A里面的shared_ptr pb_; 改为weak_ptr pb_; 

#include 

using namespace std;
class B;
class A
{
public:
	weak_ptr pb_;
	~A()
	{
		cout << "A delete\n";
	}
};
class B
{
public:
	shared_ptr pa_;
	~B()
	{
		cout << "B delete\n";
	}
};
void fun()
{
	shared_ptr pb(new B());
	shared_ptr pa(new A());
	pb->pa_ = pa;
	pa->pb_ = pb;
	cout << pb.use_count() << endl;
	cout << pa.use_count() << endl;
}
int main()
{
	fun();
	system("pause");
	return 0;
}

再次运行结果如下:

C++智能指针之weak_ptr_第1张图片

可以看到fun函数中pa ,pb之间互相引用,两个资源的引用计数为2,当要跳出函数时,智能指针pa,pb析构时两个资源引用计数会减一,但是两者引用计数还是为1,导致跳出函数时资源没有被释放(A B的析构函数没有被调用),如果把其中一个改为weak_ptr,资源B的引用开始就只有1,当pb析构时,B的计数变为0,B得到释放,B释放的同时也会使A的计数减一,同时pa析构时使A的计数减一,那么A的计数为0,A得到释放。

另外需要注意的是不能通过weak_ptr直接访问对象的方法,比如B对象中有一个方法print(),我们不能这样访问,pa->pb_->print(); 英文pb_是一个weak_ptr,应该先把它转化为shared_ptr,如:shared_ptr p = pa->pb_.lock(); p->print();

综上,weak_ptr的构造函数不会修改引用计数的值,从而不会对对象的内存进行管理,其类似一个普通指针,但不指向引用计数的共享内存,但是其可以检测到所管理的对象是否已经被释放,从而避免非法访问。

你可能感兴趣的:(C++)