Effective C++ 看完资源管理章节,做了一些简单的总结,并且实现了书中提到的一些做法。
首先,在C++中,资源是多种多样的,包括new的内存,互斥锁,IO设备等等,应用程序在占用完该设备之后都应该将设备交换给系统。
可是在实际的应用程序中做到这一点是很难的,即使自己已经考虑了各种细节,也很难避免,比如下面的例子:
class Management{...}; Management *createManagement() { return Management(); //为了简单,假设Management类具有一个默认构造函数 } void f() { Management *ptr = createManagement(); ...... delte ptr; }如果在.....部分出现了异常,或者是一个出人意料的return语句,将会直接导致ptr指向的资源泄漏,更严重的是,ptr对象指向的资源也会泄漏。
#include <iostream> #include <boost/shared_ptr.hpp> #include <assert.h> #include <memory> 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<Management> pMa(getManagement(20)); pMa->get_money(); auto_ptr<Management> pMa2 = pMa; //pMa->get_money(); //error!! pMa已经交出了资源的管理权 pMa2->get_money(); cout << "shared ptr..." << endl; shared_ptr<Management> spMa(getManagement(20)); spMa->get_money(); (*spMa).get_money(); shared_ptr<Management> spMa2 = spMa; spMa->get_money(); spMa2->get_money(); return 0; }
即:
shared_ptr<Management> spMa(getManagement(20)); void f(Management *); //call function f f(ptr.get()); //get()函数提取出实际隐含的类型
shared_ptr会在引用计数为0的时候删除该指针,这并不能满足所有的应用。比如:互斥锁,我们在使用完互斥锁之后,并不是要释放它,只是解锁unlock而已,因此我们就需要定义自己的资源管理类,如下定义了自己的mutex互斥锁资源管理类。
#include <iostream> #include <boost/shared_ptr.hpp> #include <thread> #include <assert.h> #include <mutex> #include <memory> 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<mutex> MutexPtr; }; int main() { //shared_ptr point to the array is not a good choice. will leak memory // boost::shared_ptr<int> p2Arr(new int[10]); mutex pt1; { Lock lock1(&pt1); } return 0; }PS:上述代码编译需要C++11。
shared_ptr默认在引用计数为0的时候删除该指针,也可以显式地指定该函数。如上述程序中的unlock函数。