Learn C++学习笔记:第M章—std :: weak_ptr解决std :: shared_ptr的循环依赖问题

为什么需要weak_ptr

之前介绍的std::shared_ptr可以彼此共同管理一块内存,比喻的话,有点像链表,一个指针接一个指针,然后连接到内存上,释放一个指针这个链表少一个节(指)点(针)。
所以潜在的问题就是如果是循环链表怎么办?
具体举例如下:

#include 
#include  // for std::shared_ptr
#include 
 
class Person{
	std::string m_name;
	std::shared_ptr<Person> m_partner; // initially created empty
 
public:
	Person(const std::string &name): m_name(name){ 
		std::cout << m_name << " created\n";
	}
	~Person(){
		std::cout << m_name << " destroyed\n";
	}
 
	friend bool partnerUp(std::shared_ptr<Person> &p1, std::shared_ptr<Person> &p2)	{
		if (!p1 || !p2)
			return false;
		p1->m_partner = p2;
		p2->m_partner = p1;
 
		std::cout << p1->m_name << " is now partnered with " << p2->m_name << "\n";
		return true;
	}
};
 
int main(){
	auto lucy = std::make_shared<Person>("Lucy"); // create a Person named "Lucy"
	auto ricky = std::make_shared<Person>("Ricky"); // create a Person named "Ricky"
 
	partnerUp(lucy, ricky); // Make "Lucy" point to "Ricky" and vice-versa
	return 0;
}

这个示例中,就是智能指针Lucyricky互相指向了对方,那么假如luck释放时候,发现还有一个指针ricky指针它,所以不释放内存,同理ricky指针释放的时候也不会释放内存。

对于上面的例子,很显然类Person的成员参数m_partner应该是一个观察者的角色,仅观察不拥有。也就是不参与对shared_ptr指针的计数里。
将上述代码中的:

	std::shared_ptr<Person> m_partner;

替换为:

std::weak_ptr<Person> m_partner; // note: This is now a std::weak_ptr

上面的代码即可正确运行。

怎么使用weak_ptr

std :: weak_ptr的缺点是std :: weak_ptr不能直接使用(它们没有operator->)。要使用std :: weak_ptr,必须首先将其转换为std :: shared_ptr。然后,您可以使用std :: shared_ptr。要将std :: weak_ptr转换为std :: shared_ptr,可以使用lock()成员函数。
如果上面的例子需要使用weak_ptr需要在类里面添加这样的成员函数来返回weak_ptr指针。

const std::shared_ptr<Person> getPartner() const { return m_partner.lock(); }

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