首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

关于shared_ptr的实现有关问题

2012-03-15 
关于shared_ptr的实现问题shared_ptr智能指针有个功能很强大,比如有以下的继承层次的代码:C/C++ code#incl

关于shared_ptr的实现问题
shared_ptr智能指针有个功能很强大,比如有以下的继承层次的代码:

C/C++ code
#include <iostream>using namespace std;struct Base{       Base() {cout<<"构造Base"<<endl}       ~Base() {cout<<"析构Base"<<endl;}};     //  基类的析构函数不是virtual struct Derived: Base{       Derived() {cout<<"构造Derived"<<endl}       ~Derived() {cout<<"析构Derived"<<endl;}};int main(){    { shared_ptr<Base> pb( new Derived ); }    cout<<"main"<<endl;        return 0;}

执行的结果在是能正确调用Derived的析构函数(即便基类没有定义virtual析构函数),哪位能指导一下是怎么来实现这一功能的?最好能说说实现原理及贴出实现的源代码


[解决办法]
可参考http://www.wangchao.net.cn/bbsdetail_35039.html
[解决办法]
首先的首先我要说的是:这种继承destructor不加virtual的做法是错误的,也是没有意义的。

作为一个c++标准控,让我用c++标准回答你。懒得翻译了,自己看英语。

~shared_ptr();

— If *this is empty or shares ownership with another shared_ptr instance (use_count() > 1),
there are no side effects.
— Otherwise, if *this owns an object p and a deleter d, d(p) is called.
— Otherwise, *this owns a pointer p, and delete p is called.

注意最后一句话,Otherwise, *this owns a pointer p, and delete p is called.

这里C++说到了 delete p is called。 这里其实很模糊,*this owns a pointer p,是原来Derived *的p被delete了还是转换后的Base *的p被delete了标准并没有说明。

实际的实现(clang/libc++)这里delete的确实是Derived *p。但是因为unique_ptr的实现delete的是转换到Base *的p,和shared_ptr并不统一,所以我认为是一种无心插柳的做法。


你的问题其实是:怎样实现的。以libc++为例

template<class _Tp>
class shared_ptr
{
public:
typedef _Tp element_type;
private:
element_type* __ptr_; //用来存储p
__shared_weak_count* __cntrl_; //用来存储count计数,和怎样delete p

....
};

template<class _Tp>
template<class _Yp, class>
shared_ptr<_Tp>::shared_ptr(_Yp* __p)
: __ptr_(__p) //ok, __Ptr_存储了 p
{
unique_ptr<_Yp> __hold(__p);
typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;


//注意,用来存储p,count和用来delete p (default_delete)的东东
//default_delete<_Yp>,其中_Yp 是Derived类型, _Tp是Base类型
//可以看出delete p的时候,是delete的Derived *
__cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), allocator<_Yp>());
__hold.release();
__enable_weak_this(__p);
}

热点排行