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类的析构函数
分享到:
相关推荐
(3) 在赋值操作中, 原来资源的引用计数会减一,新指向的资源引用计数会加一。 std::shared_ptr<Test> p1(new Test); std::shared_ptr<Test> p2(new Test); p1 = p2; (4) 引用计数加一/减一操作是原子性的,所
显然,许多人不喜欢标准std :: enable_... boost库也可以这样做,但是它不允许在析构函数中创建shared_ptrs,并且它不提供release()方法来获取所包含指针的所有权。 但是,不利的一面是,它还没有成为线程安全的。
C++ 智能指针(shared_ptr/weak_ptr)源码 源码位置:gcc-6.1.0\gcc-6.1.0\libstdc++-v3\include\tr1 这里只单列shared_ptr.h文件用于分析
shared_ptr arm, use arm asm code
scoped_ptrboost::scoped_ptr和std::auto_ptr非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放。下列代码演示了该指针的基本应用: 代码如下:#include <string>#include <iostream>#...
shared_ptr boost audio video AVDataPool
shared_ptr的线程安全性boost官方文档对shared_ptr线程安全性的正式表述是:shared_ptr对象提供与内置类型相同级别的线程安全性。【shared_ptrobjects offer the same level of thread safety as built-in types.】...
这是一个演示智能指针shared_ptr的一个Demo。本代码所对应的博客地址为https://blog.csdn.net/wfh2015/article/details/80699378
std::shared_ptr可以指定删除器的⼀个原 因是其默认删除器不⽀持数组对象,这⼀点需要注意。 2. 使⽤shared_ptr需要注意的问题 但凡⼀些⾼级的⽤法,使⽤时都有不少陷阱。 不要⽤⼀个原始指针初始化多个shared_ptr,...
shared_ptr与make_shared的区别 make_shared 在动态内存中分配⼀个对象并初始化它,返回指向此对象的shared_ptr,与智能指针⼀样,make_shared也定义在头⽂件 memory中。 当要⽤make_shared时,必须指定想要创建的...
C++智能指针shared_ptr讲解与使⽤ ⼿动管理的弊端 在简单的程序中,我们不⼤可能忘记释放 new 出来的指针,但是随着程序规模的增⼤,我们忘了 delete 的概率也随之增⼤。在 C++ 中 new 出来的指针,赋值意味着引⽤的...
shared_ptr采用引用计数的方式管理所指向的对象。当有一个新的shared_ptr指向同一个对象时(复制shared_ptr等),引用计数加1。当shared_ptr离开作用域时,引用计数减1。当引用计数为0时,释放所管理的内存。 这样做...
参考陈硕的多线程服务端编程>>,中的用shared_ptr实现copy-on-write技术,不过这里的线程采用的是c++11的线程库
#include <boost/shared_ptr.hpp> class CBase: public boost::enable_shared_from_this<CBase> { public: virtual void f(){}//必须有个虚函数才能向上向下转换。 } typedef boost::shared_ptr<CBase> CBasePtr; ...
四种智能指针的使用、机制和缺陷分析
C++中的智能指针首先出现在“准”标准库boost中。 随着使用的人越来越多,为了让开发人员更方便、更安全的使用动态内存,C++11也引入了智能指针来管理动态对象。 在新标准中,主要提供了shared_ptr、unique_ptr、...
和 shared_ptr 指针最⼤的不同之处在 于,unique_ptr 指针指向的堆内存⽆法同其它 unique_ptr 共享,也就是说,每个 unique_ptr 指针都独⾃拥有对其所指堆内存空间的所有 权。 这也就意味着,每个 unique_ptr 指针...
C++智能指针:shared_ptr⽤法详解 C++智能指针:shared_ptr⽤法详解 shared_ptr是C++11⾥的新特性,其包装了new操作符在堆上分配的动态对象。如: shared_ptr<int> sp1(new int(100)); //相当于 //int *sp1=new int...