为什么需要weak_ptr
之前介绍的std::shared_ptr
可以彼此共同管理一块内存,比喻的话,有点像链表,一个指针接一个指针,然后连接到内存上,释放一个指针这个链表少一个节(指)点(针)。
所以潜在的问题就是如果是循环链表怎么办?
具体举例如下:
#include <iostream>
#include <memory> // for std::shared_ptr
#include <string>
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;
}
这个示例中,就是智能指针Lucy
和ricky
互相指向了对方,那么假如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(); }