weak_ptr
weak_ptr是为了配合shared_ptr而引入的一种智能指针,它更像是 shared_ptr的一个助手而不是智能指针,它不具有普通指针的行为,没有重载operator* 和->。
用法:
#include <iostream>
#include <string>
#include <vector>
#include <boost/smart_ptr.hpp>
#include <boost/make_shared.hpp>
using namespace std;
using namespace boost;
int main()
{
boost::shared_ptr<int> sp(new int(10));
assert(sp.use_count() == 1);
//从shared_ptr创建weak_ptr,weak_ptr不影响引用计数
boost::weak_ptr<int> wp(sp);
assert(wp.use_count() == 1);
if (!wp.expired())
{
//获得一个shared_ptr
boost::shared_ptr<int> sp2 = wp.lock();
*sp2 = 100;
assert(wp.use_count() == 2);
}//退出作用域,sp2自动析构,引用计数减1
assert(wp.use_count() == 1);
//shared_ptr失效
sp.reset();
assert(wp.expired());
//weak_ptr将获得一个空指针
assert(!wp.lock());
getchar();
return 0;
}
enable_shared_from_this
weak_ptr的一个重要用途是获得this指针的shared_ptr,使对象自己能够生shared_ptr管理自己。
在头文件<boost/enable_shared_from_this.hpp>定义了一个助手类enable_shared_from_this<T>,它的声明如下:
template<class T>
class enable_shared_from_this
{
public:
shared_ptr<T> shared_from_this();
}
使用的时候只需要让想被shared_ptr管理的类从它派生即可,成员函数shared_from_this()会返回this的shared_ptr。
#include <iostream>
#include <string>
#include <vector>
#include <boost/smart_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace boost;
class self_shared : public enable_shared_from_this<self_shared>
{
public:
self_shared(int n) : x(n) {}
int x;
void print()
{
std::cout << "self_shared:" << x << std::endl;
}
};
int main()
{
auto sp = make_shared<self_shared>(333);
sp->print();
auto p = sp->shared_from_this();
p->x = 1000;
p->print();
getchar();
return 0;
}
enable_shared_from_raw
与上面类似,它不要求对象必须被一个shared_ptr管理,可以直接从一个原始指针创建出shared_ptr。
enable_shared_from_raw利用了shared_ptr别名构造函数特性,内部持有一个void*空指针shared_ptr作为引用的观察者,从而达到管理原始指针的目的。
注意:调用shared_from_raw()后,由于存在shared_ptr成员变量的原因,对象内部会有一个shared_ptr的强引用,所以即使其他的shared_ptr都析构了原始指针也不会被自动删除。
#include <iostream>
#include <string>
#include <vector>
#include <boost/smart_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
using namespace boost;
class row_shared : public enable_shared_from_raw
{
public:
row_shared()
{
std::cout << "row_shared ctor" <<std::endl;
}
~row_shared()
{
std::cout << "row_shared dtor" << std::endl;
}
};
int main()
{
row_shared x;
//此时无引用,注意用&取地址
assert(!weak_from_raw(&x).use_count());
//获取shared_ptr
auto px = shared_from_raw(&x);
//引用计数为2
assert(px.use_count() == 2);
getchar();
return 0;
}