C++11智能指针——weak_ptr
2016-03-20 22:47
621 查看
weak_ptr是为了解决shared_ptr的自引用以及交叉引用而引入的智能指针。顾名思义,weak_ptr是弱指针,因为其不具备指针的一系列操作:operator *,operator->,operator[]等,也不管理具体的原始指针。它仅仅作为一个观察者,协助shared_ptr管理原始指针。它既不使引用计数增减也不拥有原始指针,而且weak_ptr不可以直接使用原始指针进行构造,只能使用shared_ptr或另外一个weak_ptr来构造。虽然weak_ptr不管理原始指针,但是可以使用lock操作来返回一个shared_ptr。weak_ptr实现了拷贝构造函数和重载了赋值操作符,因此weak_ptr可以被用于标准容器库中的元素,例如:在一个树节点中声明子树节点std::vector<boost::weak_ptr<Node> >children。作为观察者,weak_ptr主要的操作有以下几种:
shared_ptr<T> lock() const; long use_count() const; bool expired() cosnt;//判断指针是否失效void reset(); void swap(weak_ptr<T> &b);
weak_ptr在自引用中的使用
weak_ptr很重要的一个作用是获取this指针的shared_ptr,使对象自己能够缠身管理自己的shared_ptr:对象使用weak_ptr观测this指针,并不影响引用计数,在需要的时候就调用lock函数,返回一个符合要求的shared_ptr供外界使用。这个方法被实现为一个模板类:
class enable_shared_from_this{public: shared_ptr shared_from_this();//工厂函数,产生this的shared_ptr};
使用shared_ptr管理this,必须使被管理的类public继承自enable_shared_from_this。以下为boost程序库完全开发指南第三版(page85 3.63)中的例子:
#include <iostream> #include <memory> using namespace std; class self_shared:public enable_shared_from_this<self_shared> { public: self_shared(int n):x(n){} void print() { cout << "self_shared x:" << x << endl; } int x; }; int main() { shared_ptr<self_shared> sp = make_shared<self_shared>(335); sp->print(); auto p = sp->shared_from_this(); p->x = 100; p->print(); getchar(); return 0; }
weak_ptr在交叉引用中的使用 先看一个《C++标准库——第二版》中交叉引用的例子:
#include "stdafx.h" #include <iostream> #include <string> #include <vector> #include <memory> using namespace std; #define OUT_PTR_USE_COUNT(variable) do{\ cout << #variable << ".use_count() = " << variable.use_count() << endl;\ }while(0); class Person { public: string name; shared_ptr<Person> mother; shared_ptr<Person> father; vector<shared_ptr<Person>> kids; Person(const string& n, shared_ptr<Person> m = nullptr, shared_ptr<Person> f = nullptr) : name(n), mother(m), father(f) { } ~Person() { cout << "delete " << name << endl; } }; shared_ptr<Person> initFamily(const string& name) { shared_ptr<Person> mom(new Person(name + "’s mom")); OUT_PTR_USE_COUNT(mom); //cout:1 shared_ptr<Person> dad(new Person(name + "’s dad")); shared_ptr<Person> kid(new Person(name, mom, dad)); OUT_PTR_USE_COUNT(mom); //cout:2 mom->kids.push_back(kid); dad->kids.push_back(kid); OUT_PTR_USE_COUNT(mom); //cout:2 return kid; } int main() { shared_ptr<Person> p = initFamily("nico"); cout << "- nico is shared " << p.use_count() << " times" << endl; //cout:3 return 0; //Person was not deleted when process return }
由于交叉引用,导致在工厂函数initFamily中,mom在生命周期结束时,其引用计数由2变为1,造成自身没有被析构,然后导致child一直被mom和dad所持有,在声明周期结束时也没有被析构。从运行结果来看,所有的交叉引用的person对象都没有被析构!运行结果如下:
若在交叉引用的类中使用weak_ptr代替shared_ptr所有的问题都将得到解决。
相关文章推荐
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- share_ptr的几个注意点
- 智能指针与弱引用详解
- C++ 智能指针深入解析
- C++智能指针读书笔记
- 在 Qt4 中使用 C++11
- How to get a boost::shared_ptr from this
- C++ 智能指针详解
- c++11新特性--decltype auto
- centos安装devtoolset-3支持gcc 4.9.2
- 使用eclipse编译含有C++11特性的代码
- C++智能指针(auto_ptr)详解
- 怎样在Linux环境编译支持C11
- eclipse支持c++11
- C++11可变参数函数与for循环
- vs2013 编译c++是发现惊天bug
- 简单性能测试函数模板
- 关于C++现状的一些思考
- 用C++11优化矩阵运算的空间和时间效率
- 浅析构造函数之默认构造函数