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头文件中的检查内存泄漏问题,这里是没有内存泄漏的所以:
运行结果:
---------------------------------------------------------------------------------------------------------------------------------------------------
无冥冥之志者,无昭昭之明,无惛惛之事者,无赫赫之功!