1. enable_shared_from_this
enable_shared_from_this 定义了
shared_from_this 和
weak_from_this 成员函数,它们分别返回自身的share_ptr 的weak_ptr 。
如何在对象中获得一个指向当前对象的 shared_ptr 对象 ####
使用场景 - 当类对象被 shared_ptr 管理时 - 需要在类自己定义的函数里
把当前类对象作为参数 传给其他函数时(将对象的 this
指针[raw pointer]作为返回值返回给了调用者时可能会造成的 core dump)
源码分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 namespace boost { template<class T> class enable_shared_from_this { public: shared_ptr<T> shared_from_this(); shared_ptr<T const> shared_from_this() const; weak_ptr<T> weak_from_this() noexcept; weak_ptr<T const> weak_from_this() const noexcept; template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const { if( weak_this_.expired() ) { weak_this_ = shared_ptr<T>( *ppx, py ); } } private: mutable weak_ptr<T> weak_this_; //弱引用指针数组(不能用shared_ptr,否则shared_ptr的引用永远也不为零) } //获取当前对象的shared_ptr指针就是从该weak_ptr提升而来 shared_ptr<T> shared_from_this() { shared_ptr<T> p( weak_this_ ); BOOST_ASSERT( p.get() == this ); return p; } //而weak_ptr的则是在构造的时候初始化的 explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { boost::detail::sp_enable_shared_from_this( this, p, p ); } template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe ) { if( pe != 0 ) { pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); } }
example
对一个类 Y ,当我们希望使用 shared_ptr 来管理其类对象时,可以让类 Y
从 enable_shared_from_this 继承 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <boost/enable_shared_from_this.hpp> #include <boost/shared_ptr.hpp> #include <cassert> class Y: public boost::enable_shared_from_this<Y> { public: boost::shared_ptr<Y> f() { return shared_from_this(); } }; int main() { // 正确的使用方法 boost::shared_ptr<Y> p(new Y); boost::shared_ptr<Y> q = p->f(); // 调用f获得shared_ptr assert(p == q); assert(!(p < q || q < p)); // p and q must share ownership // 错误的使用方法,因为Y的成员weak_ptr 根本就没有得到初始化 Y yy; boost::shared_ptr<Y> q = yy.f(); }
另外可见
boost官方的详细例子
实现原理
限制:
在类对象 本身 当中
不能存储 类对象本身的 shared_ptr
,否则类对象 shared_ptr
永远也不会为0了,资源永远不会释放,除非程序结束。
类对象肯定是 外部函数通过某种机制分配的,而且
一经分配立即交给 shared_ptr
管理 ,而且以后凡是需要共享使用类对象的地方必须 使用这个
shared_ptr 当作右值 来构造产生或者拷贝产生另一个
shared_ptr 从而达到共享使用的目的。
方案
类对象的外部 shared_ptr
作为函数参数 传给需要引用类对象自身的函数
【这种方法很丑陋,而且并不是所有的情况都可行(如在外部 shared_ptr
不可见的作用域中就不行)】
类对象自身存储某种信息 ,在需要 自身
shared_ptr 时来产生一个临时的 shared_ptr 。
reference
boost/enable_shared_from_this
如何用enable_shared_from_this
来得到指向自身的shared_ptr 及对enable_shared_from_this 的理解
2. noncopyable 不可拷贝类
<boost/core/noncopyable.hpp> 定义了
boost::noncopyable(不可拷贝) 类。 boost::noncopyable 使用
private (C++03版) 或者 deleted
(C++11版)字段 来限制拷贝构造函数。一个类继承自它也是不可拷贝的.
大致实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 namespace boost { class noncopyable{ # ================ c++03版本 ================ private: // emphasize the following members are private noncopyable( const noncopyable& ); noncopyable& operator=( const noncopyable& ); # ================ c++11版本 ================ public: noncopyable(const noncopyable&) = delete; noncopyable& operator=( const noncopyable& ) = delete; } }
example
private继承 boost::noncopyable,
使自定义类不能被拷贝
1 2 3 4 #include <boost/core/noncopyable.hpp> class X: private boost::noncopyable { };
3. variant class
定义
The variant
class template is a safe, generic, stack-based discriminated
union container , offering a simple solution for manipulating an
object from a heterogeneous set(elements may not be of same data
type) of types in a uniform manner. Whereas standard containers
such as std::vector may be thought of as
"multi-value, single type ," variant is
"multi-type, single value ."
Gitalking ...