以对象管理资源
通过对象的析构函数的自动调用来自动释放资源
第一部分:几种典型的以对象管理资源的例子
1. STL::auto_ptr
获取资源后立刻放入资源管理对象
std::auto_ptr<Investment> pInv(createInvestment());
当pInv生命周期结束时,自动释放资源
注意: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