shared_ptr是一个最像指针的“智能指针”,是boost.smart_ptr库中最有价值、最重要的组成部分,也是最有用的,Boost库的许多组件——甚至还包括其他一些领域的智能指针都使用了shared_ptr,所以它被毫无悬念地收入了C++11标准。
shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针0,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。
shared_ptr也可以安全地放到标准容器中,是在STL容器中存储指针的最标准解法。
实现原理
#include<iostream>
#include<vld.h>
using namespace std;
//shared_ptr
//#define TEST
class sharend_base
{
public:
sharend_base():use_count(1)
{
#ifdef TEST
cout << "Create sharend_base object." << endl;
#endif
}
virtual void dispose() = 0;//纯虚函数
virtual void destroy()
{
delete this;
}
void release()
{
if (--use_count == 0)
{
dispose();
destroy();
}
}
void add_uc()
{
++use_count;
}
~sharend_base()
{
#ifdef TEST
cout << "Free sharend_base object." << endl;
#endif
}
long u_count()const
{
return use_count;
}
private:
long use_count;
};
template<typename Y>
class sharend_conunt_impl:public sharend_base
{
public:
sharend_conunt_impl():pi(nullptr)
{
#ifdef TEST
cout << "Create sharend_conunt_impl object." << endl;
#endif
}
sharend_conunt_impl(Y*p):_pi(p)
{
#ifdef TEST
cout << "Create sharend_conunt_impl object." << endl;
#endif
}
sharend_conunt_impl(sharend_conunt_impl<Y>&p) :_pi(p._pi)
{
#ifdef TEST
cout << "Create sharend_conunt_impl object." << endl;
#endif
}
sharend_conunt_impl& operator=(sharend_conunt_impl&tm)
{
_pi = tm._pi;
}
~sharend_conunt_impl()
{
_pi=nullptr;
#ifdef TEST
cout << "Free sharend_conunt_impl object." << endl;
#endif
}
void destroy()
{
delete this;
}
void dispose()
{
delete _pi;
}
private:
Y*_pi;
};
class sharend_conunt
{
public:
sharend_conunt():pe()
{
#ifdef TEST
cout << "Create shared_conunt object." << endl;
#endif
}
template <typename V>
sharend_conunt(V*p):pe(new sharend_conunt_impl<V>(p))
{
#ifdef TEST
cout << "Create shared_conunt object." << endl;
#endif
}
sharend_conunt(sharend_conunt &p):pe(p.pe)
{
if (pe)
pe->add_uc();
#ifdef TEST
cout << "Create shared_conunt object." << endl;
#endif
}
~sharend_conunt()
{
if (pe)
pe->release();
#ifdef TEST
cout << "Free shared_conunt object." << endl;
#endif
}
sharend_conunt& operator=(const sharend_conunt&tem)
{
if (this != &tem)
{
pe = tem.pe;
if (pe)
pe->add_uc();
}
return *this;
}
long count()const
{
return pe->u_count();
}
private:
sharend_base *pe;
};
template<typename T>
class shared_ptr
{
public:
shared_ptr():px(nullptr),pn()
{
#ifdef TEST
cout << "Create shared_ptr object." << endl;
#endif
}
shared_ptr(T*p):px(p),pn(p)
{
cout << "Create shared_ptr object." << endl;
}
shared_ptr(shared_ptr<T>& r):px(r.px),pn(r.pn)
{
#ifdef TEST
cout << "Create shared_ptr object." << endl;
#endif
}
~shared_ptr()
{
#ifdef TEST
cout << "Free shared_ptr object." << endl;
#endif
}
void count()const
{
cout << "use_count="<< pn.count() << endl;
}
typedef shared_ptr<T> this_type;
shared_ptr& operator=(const shared_ptr &tmp)
{
if (this != &tmp)
{
px = tmp.px;
pn = tmp.pn;
}
return *this;
}
T & operator*()const
{
return *px;
}
T*operator->()const
{
return px;
}
private:
T*px;
sharend_conunt pn;
};
主函数:
void main(){ int *ptr = new int(10);
shared_ptr<int> ps(ptr);
cout <<*ps<<endl;
ps.count();
{
shared_ptr<int> pt = ps;
ps.count();
}
ps.count();
shared_ptr<int> pt;
pt = ps;
ps.count();}
小编实现的是只有一些基础功能的,真正的还要看源码。
这里面要注意的就是sharend_conunt_impl这个类的子类对象要进行自杀,否则会出现内存泄漏。
下面就是vld.h头文件中的检查内存泄漏问题,这里是没有内存泄漏的所以:
运行结果:
---------------------------------------------------------------------------------------------------------------------------------------------------
无冥冥之志者,无昭昭之明,无惛惛之事者,无赫赫之功!

