/* 智能指针weak_ptr */
#include <iostream>
#include <string>
#include <memory>
/*
weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象.
进行该对象的内存管理的是那个强引用的 shared_ptr. weak_ptr只是提供了对管理对象的一个访问手段.
weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作,
它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少.
weak_ptr 定义在 memory 文件中(非memory.h), 命名空间为 std.
weak_ptr 初始化:
方式一:构造函数构造
std::shared_ptr<int> sp(new Student);
std::weak_ptr<int> wp(sp);
方式二:赋值初始化
std::shared_ptr<int> sp(new int(10));
wp = sp;
方式三:通过weak_ptr 对象构造
*/
/*
成员函数
weak_ptr 没有重载*和->但可以使用 lock 获得一个可用的 shared_ptr 对象. 注意, weak_ptr 在使用前需要检查合法性.
expired 用于检测所管理的对象是否已经释放, 如果已经释放, 返回 true; 否则返回 false.
lock 用于获取所管理的对象的强引用(shared_ptr). 如果 expired 为 true, 返回一个空的 shared_ptr; 否则返回一个 shared_ptr,
其内部对象指向与 weak_ptr 相同.
use_count 返回与 shared_ptr 共享的对象的引用计数.
reset 将 weak_ptr 置空.
weak_ptr 支持拷贝或赋值, 但不会影响对应的 shared_ptr 内部对象的计数.
*/
struct Student
{
public:
Student(std::string name_, int age_) :name(name_), age(age_) {}
std::string name;
int age;
};
void test()
{
//初始化方式一
std::shared_ptr<Student> sp1(new Student("tom",11));
std::weak_ptr<Student> wp1(sp1);
//初始化方式二
std::weak_ptr<Student> wp2 = sp1;
//初始化方式三
std::weak_ptr<Student> wp3 = wp2;
//weak_ptr 在使用前需要检查合法性
if (!wp3.expired())
{
//weak_ptr 没有重载*和->但可以使用 lock 获得一个可用的 shared_ptr 对象
std::shared_ptr<Student> tmp = wp3.lock();
printf("name is [%s] .\n", tmp->name.c_str());
}
std::weak_ptr<Student> wp4;
{
std::shared_ptr<Student> sp2(new Student("jack",10));
wp4 = sp2;
printf("%d\n", wp4.use_count()); // 1
wp4.reset();
printf("%d\n", wp4.use_count()); // 0
printf("%d\n", sp2.use_count()); // 1
//weak_ptr不会影响引用记数的增加或减少
}
//当weak_ptr引用对象被析构之后,lock(0方法返回值为NULL
std::shared_ptr<Student> spnull = wp4.lock();
if (NULL == spnull)
{
printf("shared_ptr is not Usable .\n");
}
}
int main()
{
test();
getchar();
return 0;
}