本文主要是介绍C++-标准库 weak_ptr,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 概述
- 构建
- cyclic reference例子
概述
shared_ptr的作用主要是在最后一个指向资源的shared_ptr销毁时自动释放资源,然而在某些场景下这种行为可能不被期望。例如:
- 两个或者多个对象都使用shared_ptr,并且相互通过shared_ptr指向对方,如果存在一个环路(cyclic reference),那么由于环路上的shared_ptr的use_count最终无法降为0,所以环路上的资源将无法被释放。
- 当我们想使用“希望共享但不拥有”某个对象的语义的情况下,shared_ptr也无法提供此语义。
因此weak_ptr可以在这两种场景下使用。
构建
weak_ptr可以通过shared_ptr构建以及赋值
shared_ptr<ClassA> spA(new ClassA);
weak_ptr<ClassA> wpA1(spA);
weak_ptr<ClassA> wpA2 = spA;
cyclic reference例子
#include <iostream>
#include <memory>
using namespace std;class Person
{
public:Person(const string& name){m_name = name;}~Person(){cout << "destroy: " << m_name << endl;}void meetSomeone(shared_ptr<Person> someone){m_otherOne = someone;}
public:string m_name;std::shared_ptr<Person> m_otherOne;
};int main()
{shared_ptr<Person> Alice(new Person("Alice"));shared_ptr<Person> Bob(new Person("Bob"));cout << "Alice use count: " << Alice.use_count() << endl;cout << "Bob use count: " << Bob.use_count() << endl;Alice->meetSomeone(Bob); // --> 1Bob->meetSomeone(Alice); // --> 2cout << "Alice use count: " << Alice.use_count() << endl;cout << "Bob use count: " << Bob.use_count() << endl;return 0;
}
程序输出
Alice use count: 1
Bob use count: 1
Alice use count: 2
Bob use count: 2
对Alice Person而言,共有两个shared_ptr指向它,一个是作用域内的Alice shared_ptr,一个是Bob Person中的m_otherOne;Bob Person同理。
可以看到最终对象并没有被释放,这是因为main结束时,先析构Bob shared_ptr(声明逆序析构),此时Bob shared_ptr的use_count为2,析构函数内use_count减为1,因此不会释放Bob Person对象。接着释放Alice shared_ptr,与前面同理不会释放Alice Person对象。
尝试注释第1处,输出变为:
Alice use count: 1
Bob use count: 1
Alice use count: 2
Bob use count: 1
destroy: Bob
destroy: Alice
读者可以按照上面的思路自己解释一下这个结果。
为了避免上述这样的循环引用(cyclic reference)我们可以进行如下改动:
std::weak_ptr<Person> m_otherOne; // weak_ptr!!
此时输出结果为:
Alice use count: 1
Bob use count: 1
Alice use count: 1
Bob use count: 1
destroy: Bob
destroy: Alice
使用weak_ptr时访问对象的方式有所变化:
Alice->m_otherOne->m_name; // shared_ptr访问对象方式
Alice->m_otherOne.lock()->m_name; // weak_ptr访问对象方式
lock函数返回一个从weak_ptr构建的shared_ptr,通过此shared_ptr我们可以访问对象。
(未完待续…)
这篇关于C++-标准库 weak_ptr的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!