0%

[c++接口] 1.boost常用接口

1. enable_shared_from_this#

enable_shared_from_this定义了 shared_from_thisweak_from_this成员函数,它们分别返回自身的share_ptrweak_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#

  1. boost/enable_shared_from_this
  2. 如何用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."