以對象管理資源
通過對象的析構函數的自動調用來自動釋放資源
第一部分:幾種典型的以對象管理資源的例子
1. STL::auto_ptr
獲取資源後立刻放入資源管理對象
std::auto_ptrpInv(createInvestment());
注意:auto_ptr有一個奇怪的性質:不會有多個auto_ptr同時指向同一個資源。
std::auto_ptrauto_ptr在復制或者賦值時,轉移底部資源的所有權pInv2(pInv); // pInv2 指向對象,pInv設為null pInv = pInv2; //pInv指向對象,pInv2為null
2. RCSP(引用計數型智能指針)
持續追蹤共有多少個對象指向某一資源,並在無人指向它時自動釋放資源。。類似於Java的垃圾回收機制。
e.g. TR1::shared_ptr
下面是一個簡單的Reference counting的智能指針
// copyright @ L.J.SHOU Dec.23, 2013 // class for managing pointer, smart pointer class #ifndef HAS_PTR_H_ #define HAS_PTR_H_ #includeclass HasPtr; class U_Ptr { friend class HasPtr; int *ip; size_t use; U_Ptr(int *p): ip(p), use(1) { } ~U_Ptr() { delete ip; } }; class HasPtr { public: HasPtr(int *p, int i) : ptr(new U_Ptr(p)), val(i) {} // copy members and increment the use count HasPtr(const HasPtr &rhs): ptr(rhs.ptr), val(rhs.val) { ++ ptr->use; } HasPtr& operator=(const HasPtr &rhs); // if use count goes to zero, delete the U_Ptr object ~HasPtr() { if(--ptr->use == 0) delete ptr; } int *get_ptr() const { return ptr->ip; } int get_int() const { return val; } void set_ptr(int *p) { ptr->ip = p; } void set_int(int i) { val = i; } int get_ptr_val() const { return *ptr->ip; } int set_ptr_val(int i) { *ptr->ip = i; } private: U_Ptr * ptr; // pointer to use-counted U_Ptr class int val; }; // increment rhs's use count first to avoid self assignment HasPtr& HasPtr::operator=(const HasPtr &rhs) { ++ rhs.ptr->use; // increment use count on rhs first if(--ptr->use == 0) delete ptr; // if use count goes to zero, delete object ptr = rhs.ptr; val = rhs.val; return *this; } #endif
第二部分:如何處理資源管理對象的復制操作
C++中,通過類的copy constructor 和 copy assignment來控制資源對象的復制。
通常有以下四種策略:
1. 禁止復制:將copy constructor 和copy assignment聲明為private, 並不給予實現
2. 引用計數法:賦值時,資源的“被引用數”增加1。例如shared_ptr
3. 復制底部資源:每個對象擁有各自的資源,不能實現資源共享
4. 轉移底部資源的擁有權:e.g. std::auto_ptr