shared_ptr 是为了解决 auto_ptr 在对象所有权上的局限性(auto_ptr 是独占的), 在使用引用计数的机制上提供了可以共享所有权的智能指针, 当然这需要额外的开销:
(1) shared_ptr 对象除了包括一个所拥有对象的指针外, 还必须包括一个引用计数代理对象的指针。
(2) 时间上的开销主要在初始化和拷贝操作上, *和->操作符重载的开销跟auto_ptr是一样。
(1) shared_ptr 对象除了包括一个所拥有对象的指针外, 还必须包括一个引用计数代理对象的指针。
(2) 时间上的开销主要在初始化和拷贝操作上, *和->操作符重载的开销跟auto_ptr是一样。
(3) 开销并不是我们不使用shared_ptr的理由, 永远不要进行不成熟的优化, 直到性能分析器告诉你这一点。
代码实现:
使用单例模式进行shared_ptr的实现
#include <iostream> using namespace std; class RefManage { public: static RefManage* getInstance() { return &rm; } private: RefManage() :length(0) {} RefManage(const RefManage& rhs); public: void addRef(void* ptr) { if (ptr != NULL) { int index = Find(ptr); if (index < 0) { /*arr[length].addr = ptr; arr[length++].refcount++;*/ Node tmp(ptr, 1); arr[length++] = tmp; } else { arr[index].refcount++; } } } void delRef(void* ptr) { if (ptr != NULL) { int index = Find(ptr); if (index < 0) { throw exception("addr is not exist"); } else { if (arr[index].refcount != 0) { arr[index].refcount--; } } } } /* 1.NULL 0 2.not find -1 3.find refcount */ int getRef(void* ptr) { if (ptr == NULL) { return 0; } int index = Find(ptr); if (index < 0) { return -1; } else { return arr[index].refcount; } } private: int Find(void* ptr) { for (int i = 0; i < length; ++i) { if (arr[i].addr == ptr) { return i; } } return -1; } class Node { public: Node(void* ptr, int ref = 0) { addr = ptr; refcount = ref; } Node() { memset(this, 0, sizeof(Node)); } public: void* addr; int refcount; }; Node arr[10]; int length;///有效节点个数 当前要插入的节点下标 static RefManage rm; }; RefManage RefManage::rm; template<typename T> class Shared_ptr { public: Shared_ptr(T* ptr = NULL) :mptr(ptr) { AddRef(); } Shared_ptr(const Shared_ptr<T>& rhs) :mptr(rhs.mptr) { AddRef(); } Shared_ptr<T>& operator=(const Shared_ptr<T>& rhs) { if (this != &rhs) { DelRef(); if (GetRef() == 0) { delete mptr; } mptr = rhs.mptr; AddRef(); } return *this; } ~Shared_ptr() { DelRef(); if (GetRef() == 0) { delete mptr; } mptr = NULL; } T* operator->() { return mptr; } T& operator*() { return *mptr; } private: void AddRef() { rm->addRef(mptr); } void DelRef() { rm->delRef(mptr); } int GetRef() { return rm->getRef(mptr); } T* mptr; static RefManage* rm; }; template<typename T> RefManage* Shared_ptr<T>::rm = RefManage::getInstance(); class B; class A { public: A() { cout << "A()" << endl; } ~A() { cout << "~A()" << endl; } Shared_ptr<B> pa; }; class B { public: B() { cout << "B()" << endl; } ~B() { cout << "~B()" << endl; } Shared_ptr<A> pb; }; int main() { Shared_ptr<A> spa(new A()); Shared_ptr<B> spb(new B()); spa->pa = spb; spb->pb = spa; //int *p = new int; //Shared_ptr<int> sp1(p); //Shared_ptr<int> sp2(p); //Shared_ptr<int> sp3(p); //Shared_ptr<int> sp4(p); return 0; }
运行结果: