`
chaoslawful
  • 浏览: 196589 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

避免boost::shared_ptr管理的共享对象在其外被无意中删除

阅读更多
boost::shared_ptr(已进入C++ TR1标准)是管理共享对象的好帮手,但由于能用其get()方法获取原对象裸指针,因此存在其管理的对象被人为意外删除的危险。最近看boost相关资料时发现一些方法能避免该问题:

方案1:使用包装类
class T {
protected:
    ~T() {...}
public:
    ....
};

class TWrapper {
};

boost::shared_ptr<T> p(new TWrapper);
delete p.get();    // Oops...编译期错误

这是因为shared_ptr对象内部指向的共享引用计数对象保存的是原始指针(这里就是TWrapper*),引用计数为0时可以用该指针正常调用delete,而从get()方法获得的是shared_ptr对象缓存的指针,类型为T*,而class T的析构函数被保护了,故不能显式被delete。该方案缺点是需要引入一个新类,且当原类构造函数有多种形式时,包装类也要对应提供这些形式的构造函数,二者是紧耦合的;优点是创建对象方式同以前没有变化。

方案2:使用自定义析构函数
class T {
    struct deleter {
        void operator() (T *p) { delete p; }
    };
    friend class deleter;
protected:
    T() {...}
    ~T() {...}
public:
    static boost::shared_ptr<T> createObject()
    {
        return boost::shared_ptr<T>(new T(), T::deleter());
    }
};

boost::shared_ptr<T> p = T::createObject();
delete p.get();    // Oops...编译期错误

该方案利用shared_ptr的自定义析构函数形式实现,将析构函子类作为私有类封装在class T内部,以避免被外部直接利用;创建对象时也不再使用标准new形式,而是封装了对应的静态工厂方法,为了避免绕过工厂方法创建对象,还要将class T的构造函数也保护起来。该方案的缺点是创建对象方法彻底改变,且工厂方法接口要同原有类构造函数的形式一致;优点是所有的机制都封装在原有类内部,不需要额外引入新类型。

从shared_ptr内部的共享引用计数对象保存原始指针这一特性可知,若创建shared_ptr对象时传入的是派生类指针,即使基类没有将析构函数定义为virtual的,共享对象被删除时也会正常调用派生类的析构函数:
class Base {
public:
    ~Base() { cout << "Base dtor\n"; }
};

class Derived:virtual public Base {
public:
    ~Derived() { cout << "Derived dtor\n"; }
};

{
    boost::shared_ptr<Base> p(new Derived);
}    // shared_ptr对象在此释放管理的对象,会顺序调用Derived和Base类的析构函数

Base *q=new Derived;
delete q;    // 这里因为Base类的析构函数不是virtual的,因此这里只会调用Base类的析构函数

分享到:
评论

相关推荐

    C++11 std::shared_ptr总结与使用示例代码详解

    (3) 在赋值操作中, 原来资源的引用计数会减一,新指向的资源引用计数会加一。 std::shared_ptr&lt;Test&gt; p1(new Test); std::shared_ptr&lt;Test&gt; p2(new Test); p1 = p2; (4) 引用计数加一/减一操作是原子性的,所

    shared_from_this() in Constructor:直接替换std :: shared_ptr + std :: enable_shared_from_this-开源

    显然,许多人不喜欢标准std :: enable_... boost库也可以这样做,但是它不允许在析构函数中创建shared_ptrs,并且它不提供release()方法来获取所包含指针的所有权。 但是,不利的一面是,它还没有成为线程安全的。

    C++ 智能指针(shared_ptr/weak_ptr)源码

    C++ 智能指针(shared_ptr/weak_ptr)源码 源码位置:gcc-6.1.0\gcc-6.1.0\libstdc++-v3\include\tr1 这里只单列shared_ptr.h文件用于分析

    shared_ptr for arm

    shared_ptr arm, use arm asm code

    浅析Boost智能指针:scoped_ptr shared_ptr weak_ptr

    scoped_ptrboost::scoped_ptr和std::auto_ptr非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放。下列代码演示了该指针的基本应用: 代码如下:#include &lt;string&gt;#include &lt;iostream&gt;#...

    shared_ptr

    shared_ptr boost audio video AVDataPool

    shared_ptr线程安全性全面分析

    shared_ptr的线程安全性boost官方文档对shared_ptr线程安全性的正式表述是:shared_ptr对象提供与内置类型相同级别的线程安全性。【shared_ptrobjects offer the same level of thread safety as built-in types.】...

    智能指针shared_ptr的Demo

    这是一个演示智能指针shared_ptr的一个Demo。本代码所对应的博客地址为https://blog.csdn.net/wfh2015/article/details/80699378

    智能指针shared-ptr的用法.pdf

    std::shared_ptr可以指定删除器的⼀个原 因是其默认删除器不⽀持数组对象,这⼀点需要注意。 2. 使⽤shared_ptr需要注意的问题 但凡⼀些⾼级的⽤法,使⽤时都有不少陷阱。 不要⽤⼀个原始指针初始化多个shared_ptr,...

    shared-ptr(智能指针)举例.pdf

    shared_ptr与make_shared的区别 make_shared 在动态内存中分配⼀个对象并初始化它,返回指向此对象的shared_ptr,与智能指针⼀样,make_shared也定义在头⽂件 memory中。 当要⽤make_shared时,必须指定想要创建的...

    C++智能指针shared-ptr讲解与使用.pdf

    C++智能指针shared_ptr讲解与使⽤ ⼿动管理的弊端 在简单的程序中,我们不⼤可能忘记释放 new 出来的指针,但是随着程序规模的增⼤,我们忘了 delete 的概率也随之增⼤。在 C++ 中 new 出来的指针,赋值意味着引⽤的...

    C++11新特性之智能指针(shared_ptr/unique_ptr/weak_ptr)

    shared_ptr采用引用计数的方式管理所指向的对象。当有一个新的shared_ptr指向同一个对象时(复制shared_ptr等),引用计数加1。当shared_ptr离开作用域时,引用计数减1。当引用计数为0时,释放所管理的内存。 这样做...

    用shared_ptr实现多线程对全局变量的读写,copy-on-write技术

    参考陈硕的多线程服务端编程&gt;&gt;,中的用shared_ptr实现copy-on-write技术,不过这里的线程采用的是c++11的线程库

    C++智能指针详解.pdf

    #include &lt;boost/shared_ptr.hpp&gt; class CBase: public boost::enable_shared_from_this&lt;CBase&gt; { public: virtual void f(){}//必须有个虚函数才能向上向下转换。 } typedef boost::shared_ptr&lt;CBase&gt; CBasePtr; ...

    C++ unique_ptr weak_ptr shared_ptr auto_ptr智能指针.doc

    四种智能指针的使用、机制和缺陷分析

    C++11 智能指针之shared_ptr代码详解

    C++中的智能指针首先出现在“准”标准库boost中。 随着使用的人越来越多,为了让开发人员更方便、更安全的使用动态内存,C++11也引入了智能指针来管理动态对象。 在新标准中,主要提供了shared_ptr、unique_ptr、...

    C++智能指针-unique-ptr智能指针详解.pdf

    和 shared_ptr 指针最⼤的不同之处在 于,unique_ptr 指针指向的堆内存⽆法同其它 unique_ptr 共享,也就是说,每个 unique_ptr 指针都独⾃拥有对其所指堆内存空间的所有 权。 这也就意味着,每个 unique_ptr 指针...

    C++智能指针:shared-ptr用法详解.pdf

    C++智能指针:shared_ptr⽤法详解 C++智能指针:shared_ptr⽤法详解 shared_ptr是C++11⾥的新特性,其包装了new操作符在堆上分配的动态对象。如: shared_ptr&lt;int&gt; sp1(new int(100)); //相当于 //int *sp1=new int...

Global site tag (gtag.js) - Google Analytics