本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
经验1:为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源
示例:f函数履行删除工厂函数生成的类
class Investment{ //"投资类型"继承体系中的root class }; Investment *createInvestment();//返回指针,指向Investment继承体系内的动态分配对象。调用者有责任删除它。 void f(){ Investment *pInv = createInvestment(); //调用factory函数 //... delete pInv; }
解析: f 可能由于某些原因,控制流无法触及delete语句,泄漏的不只是内含投资对象的那块内存,还包括那些投资对象所保存的任何资源
纠正:把资源放进对象内,依赖C++的“析构函数自动调用机制”确保资源被释放。
class Investment{ //"投资类型"继承体系中的root class }; Investment *createInvestment();//返回指针,指向Investment继承体系内的动态分配对象。调用者有责任删除它。 void f(){ std::auto_ptr<Investment> pInv(createInvestment()); //调用factory函数,一如既往地使用pInv,经由auto_ptr的析构函数自动删除pInv //... }
解析:
获得资源后立刻放进管理对象内
管理对象运用析构函数确保资源被释放
而管理对象的析构函数会在管理对象离开作用域后被自动调用
经验2:两个常被使用的RAII classes分别是tr1::shared_ptr和auto_ptr。前者通常是较佳选择,因为其copy行为比较直观。若选择auto_ptr,复制动作会使它(被复制物)指向null
示例:使用std::auto_ptr和使用std::tr1::shared_ptr 的对比 (代码来自: http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c15361/A-TR1-Tutorial-Smart-Pointers.htm )
#include <memory> #include <iostream> class foo{ public: void print(){std::cout << "foo::print" << std::endl;} }; int main(){ std::auto_ptr<foo> ap1(new foo); ap1->print(); std::cout << "ap1 pointer: " << ap1.get() << std::endl; std::auto_ptr<foo> ap2(ap1); ap2->print(); std::cout << "ap1 pointer: " << ap1.get() << std::endl; std::cout << "ap2 pointer: " << ap2.get() << std::endl; system("pause"); return 0; }
foo::print
ap1 pointer: 0052B238
foo::print
ap1 pointer: 00000000
ap2 pointer: 0052B238
解析:auto_ptr,复制动作会使它(被复制物)指向null
#include <memory> #include <iostream> class foo{ public: void print(){std::cout << "foo::print" << std::endl;} }; int main(){ std::tr1::shared_ptr<foo> sp1(new foo); sp1->print(); std::cout << "sp1 pointer: " << sp1.get() << std::endl; std::tr1::shared_ptr<foo> sp2(sp1); sp2->print(); std::cout << "sp1 pointer: " << sp1.get() << std::endl; std::cout << "sp2 pointer: " << sp2.get() << std::endl; std::cout << "counter sp1: " << sp1.use_count() << std::endl; std::cout << "counter sp2: " << sp2.use_count() << std::endl; system("pause"); return 0; }
输出:
foo::print
sp1 pointer: 006BB238
foo::print
sp1 pointer: 006BB238
sp2 pointer: 006BB238
counter sp1: 2
counter sp2: 2
解析:
std::tr1::shared_ptr 持续追踪共有多少对象指向某笔资源,并在无人指向它时自动删除该资源。