Effective C++ 看完资源管理章节,做了一些简单的总结,并且实现了书中提到的一些做法。
首先,在C++中,资源是多种多样的,包括new的内存,互斥锁,IO设备等等,应用程序在占用完该设备之后都应该将设备交换给系统。
可是在实际的应用程序中做到这一点是很难的,即使自己已经考虑了各种细节,也很难避免,比如下面的例子:
class Management{...};
Management *createManagement()
{
return Management(); //为了简单,假设Management类具有一个默认构造函数
}
void f()
{
Management *ptr = createManagement();
......
delte ptr;
}如果在.....部分出现了异常,或者是一个出人意料的return语句,将会直接导致ptr指向的资源泄漏,更严重的是,ptr对象指向的资源也会泄漏。
因此,如果有一个负责“资源管理”的对象,那么我们就可以将“资源泄漏”的危机移交给这样的对象了(至少在很大程度上是这样)。
所幸的是,在C++中存在auto_ptr , shared_ptr这样的指针,可以用来封装需要管理的对象指针,而用户不需要担心在什么时候调用delete。什么时候需要释放资源了。
PS:auto_ptr保证某资源在任何时候只有一个指针指向它,因此,“赋值”对于auto_ptr来说,是移交了资源的管理权。
shared_ptr则是使用“reference_counting”来标志当前的资源是否可以被释放,即如果指向当前资源的指针计数为0的话,那么则可以释放该资源。
下面的程序简要的介绍了使用auto_ptr以及shared_ptr的使用方法,
#include#include #include #include using namespace std; //using namespace boost; class Management { private: int money; public: Management(int _money = 0 ):money(_money){} ~Management(){} void get_money(){cout << money << endl;} }; Management *getManagement(int _val = 0) { return new Management(_val); } int main() { Management *ptr = getManagement(10); ptr->get_money(); delete ptr; cout << "auto ptr..." << endl; auto_ptr pMa(getManagement(20)); pMa->get_money(); auto_ptr pMa2 = pMa; //pMa->get_money(); //error!! pMa已经交出了资源的管理权 pMa2->get_money(); cout << "shared ptr..." << endl; shared_ptr spMa(getManagement(20)); spMa->get_money(); (*spMa).get_money(); shared_ptr spMa2 = spMa; spMa->get_money(); spMa2->get_money(); return 0; }
在程序中,我们使用了shared_ptr封装了指针,但是如果在实际的应用中,我们需要Management指针怎么办,所幸的是shared_ptr的get函数用来提取该指针实际的类型。
< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+vLSjujwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">shared_ptr
shared_ptr会在引用计数为0的时候删除该指针,这并不能满足所有的应用。比如:互斥锁,我们在使用完互斥锁之后,并不是要释放它,只是解锁unlock而已,因此我们就需要定义自己的资源管理类,如下定义了自己的mutex互斥锁资源管理类。
#includePS:上述代码编译需要C++11。#include #include #include #include #include using namespace std; //using namespace boost; // define own resource Management class void unlock(mutex *MutexPtr) { cout << "unlock ..." << endl; MutexPtr->unlock(); cout << "unlock end ..." << endl; } class Lock { public: explicit Lock(mutex *pm):MutexPtr(pm,unlock) //unlock函数在引用基数为0时调用函数unlock { cout << "Lock construction..." << endl; (MutexPtr.get())->lock(); //the parameter of lock is a pointer of Mutex cout << "Lock contruction end..." << endl; } private: shared_ptr MutexPtr; }; int main() { //shared_ptr point to the array is not a good choice. will leak memory // boost::shared_ptr p2Arr(new int[10]); mutex pt1; { Lock lock1(&pt1); } return 0; }
shared_ptr默认在引用计数为0的时候删除该指针,也可以显式地指定该函数。如上述程序中的unlock函数。
