`
chaoslawful
  • 浏览: 198421 次
  • 性别: 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 下使用 Boost.Serialization 库实现智能指针的序列化

    在C++11及更高版本中,智能指针(如`std::unique_ptr`,`std::shared_ptr`和`std::scoped_ptr`)被引入来更好地管理动态内存,因此理解如何在这些指针上实现序列化至关重要。 首先,让我们关注`std::unique_ptr`。`...

    浅析Boost智能指针:scoped_ptr shared_ptr weak_ptr

    2. **生命周期绑定**:`boost::scoped_ptr` 所管理的对象在其作用域结束时自动删除,不能作为函数返回值或存储在STL容器中。 3. **不支持数组管理**:由于它使用`delete`而非`delete[]`释放对象,因此不能管理动态...

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

    std::shared_ptr是C++11中引入的一种智能指针,主要用于自动管理资源的生命周期。下面是std::shared_ptr的总结和使用示例代码详解: 一、智能指针的用途 std::shared_ptr的主要用途是方便资源的管理,自动释放没有...

    智能指针shared_ptr的Demo

    在C++中,`shared_ptr`通常用于替代原始指针,特别是在需要传递对象所有权或者多个对象需要共享同一资源的场景。例如,当函数需要返回一个动态分配的对象时,可以使用`shared_ptr`作为返回类型,这样接收者就可以...

    shared_ptr只能对new的内存操作

    在C++标准库中,`std::shared_ptr`(在早期版本中可能使用`boost::shared_ptr`)是一种智能指针,它通过引用计数来管理动态分配的对象生命周期。`std::shared_ptr`的设计目的是自动管理对象的内存,当最后一个指向该...

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

    在 C++ 中,有四种智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,每种智能指针都有其特点和使用场景。 一、auto_ptr auto_ptr 是 C++98 中引入的智能指针,它可以自动释放动态分配的内存。但是,auto_...

    test_share_ptr

    当最后一个`std::shared_ptr`被销毁时,其所指向的对象也会随之被删除。 在C++中,传统的裸指针(如`int*`)需要程序员手动管理内存,容易出现忘记释放或过早释放的问题,而智能指针通过RAII(Resource Acquisition...

    shared_ptr

    在智能指针家族中,`shared_ptr`和`weak_ptr`是TR1(Technical Report 1)的一部分,也被称为Boost库的一部分,并被整合到了C++11标准中。 ### shared_ptr `shared_ptr`是一种引用计数智能指针,当一个`shared_ptr...

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

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

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

    智能指针是C++中用于自动管理动态分配内存的一种工具,它可以确保在适当的时候自动释放内存,从而避免内存泄漏的问题。其中,`unique_ptr`是一种特殊的智能指针,它拥有对所指向内存的唯一所有权,不允许与其他`...

    C++ 中boost::share_ptr智能指针的使用方法

    使用 boost::shared_ptr 智能指针需要首先编译 Boost 库,然后在代码中包含头文件 &lt;boost/shared_ptr.hpp&gt;。 1. 创建智能指针 使用 boost::shared_ptr 智能指针可以创建一个对象,例如: ```cpp boost::shared_ptr...

    奇妙的C++——智能指针

    当最后一个引用该对象的std::shared_ptr被销毁时,对象会被自动删除。它通过内部计数器来跟踪引用数量。 3. **std::weak_ptr**:std::weak_ptr是std::shared_ptr的辅助类,它不增加对象的引用计数,而是保持对对象...

    智能指针的各种实现方法

    智能指针作为一种在C++中管理动态分配内存的机制,其设计目的是为了自动处理资源的生命周期,避免资源泄漏和悬挂指针等问题。在C++标准库(STL)以及Boost库中,提供了多种智能指针的实现方式,每种都有其特定的应用...

    stl中的智能指针

    boost::shared_ptr 是 Boost 库中的智能指针,它可以管理多个堆内存对象。它可以被复制和赋值,每个复制的智能指针都指向同一个堆对象。 五、boost::scoped_array boost::scoped_array 是 Boost 库中的智能指针,...

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

    因此,多个shared_ptr可以共享同一个对象,但需要注意的是,不应该用原始指针直接初始化多个shared_ptr,这样可能导致对象被多次删除。 初始化shared_ptr的方式包括构造函数、std::make_shared辅助函数以及reset...

    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文件用于分析

    C++智能指针详解.pdf

    1. **std::auto_ptr**:在C++98和C++03中,std::auto_ptr是最早的智能指针之一,但在C++11中被弃用,因为它不满足现代C++的内存管理需求。std::auto_ptr具有所有权的概念,一个std::auto_ptr对象一旦被赋值给另一个...

    c++智能指针

    std::weak_ptr的典型用法是,当你想用一个指针来跟踪一个对象,但是不想阻止这个对象被删除时,例如在观察者模式中一个观察者需要知道何时被观察的对象被销毁。由于std::weak_ptr不持有对象的所有权,它提供了...

Global site tag (gtag.js) - Google Analytics