c++学习系列(2)---shared_ptr的实现和代码例子版本0.2
本文主要介绍: shared_ptr中为什么需要enable_shared_from_this 这个基类,以及shared_ptr中是如何实现这个功能的。代码中如何实现。
问题1: 代码中为什么需要enable_shared_from_this 这个基类。在类对象内部需要生成一个共享指针;如下:
#include<iostream>
#include<memory>
using namespace std;
class base{
public:
base(){}
~base(){cout<<"destruct"<<endl;}
shared_ptr<base> get_ptr(){return shared_ptr<base>(this);}
};
int main(){
shared_ptr<base> pdata1(new base);
shared_ptr<base> pdata2 = pdata1->get_ptr();
return 0;
}
在这种情况下,就会存在内存的重复释放。执行结果如下:

修改代码如下就可以避免对象重复释放的情况:
#include<iostream>
#include<memory>
using namespace std;
class base:public enable_shared_from_this<base> {
public:
base(){}
~base(){cout<<"destruct"<<endl;}
shared_ptr<base> get_ptr(){return shared_from_this();}
};
int main(){
shared_ptr<base> pdata1(new base);
shared_ptr<base> pdata2 = pdata1->get_ptr();
return 0;
}
这种情况下就不会存在内存重复释放的的情况。
问题2: shared_ptr是如何实现这个enable_shared_from_this 这个功能。
查看boost源码:enable_shared_from_this 中有一个weak_ptr的成员。在构造share_ptr的构造函数中,会加载函数sp_pointer_construct ,这个函数会调用sp_enable_shared_from_this,share_ptr 中实现了两个sp_enable_shared_from_this,具体的声明如下:
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
{
boost::detail::shared_count( p ).swap( pn );
boost::detail::sp_enable_shared_from_this( ppx, 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 ) );
}
}
inline void sp_enable_shared_from_this( ... )
{
}
其中指针p是 智能指针指向的对象,如果该对象没有继承基类对象enable_shared_from_this,则会调用一个空函数 sp_enable_shared_from_this。c++11利用了重载的特性,巧妙的实现了这个特性。可以看一个sample如下:
#include<iostream>
#include<memory>
using namespace std;
class Node{
};
class Nodederive:public Node{
};
class base {
public:
base(Nodederive* pdata){process_node(pdata);}
~base(){cout<<"destruct"<<endl;}
void process_node(Node* pdata){cout<<"node process"<<endl;}
void process_node(...){cout<<"nothging"<<endl;}
};
int main(){
Nodederive node;
shared_ptr<base> pdata1(new base(&node));
return 0;
}
如果 类Nodederive不继承Node的话,则构造函数会调用 process_node(...)函数。
因此结论是,在实现shared_ptr接口的时候,要声重载sp_enable_shared_from_this 函数。
代码见https://github.com/wudafucode/cc/tree/master/shared_ptr
浙公网安备 33010602011771号