以对象管理资源
通过对象的析构函数的自动调用来自动释放资源
第一部分:几种典型的以对象管理资源的例子
1. STL::auto_ptr
获取资源后立刻放入资源管理对象
std::auto_ptr<Investment> pInv(createInvestment());
注意:auto_ptr有一个奇怪的性质:不会有多个auto_ptr同时指向同一个资源。
std::auto_ptr<Investment> pInv2(pInv);
// pInv2 指向对象,pInv设为null
pInv = pInv2;
//pInv指向对象,pInv2为null
auto_ptr在复制或者赋值时,
转移底部资源的所有权
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_ #include <iostream> class 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