在c++程序中,內存管理中經常隱藏著很深的bug。 雖然我們一般可以采用vector,string,map等容器自動管理內存,但涉及多態(tài),繼承的時候也不可避免的要手動管理,c++標準庫中提供的auto_ptr能一定程度上幫助我們。auto_ptr用法:1.需要包含頭文件2.Constructor:explicit auto_ptr(X* p = 0) throw();將指針p交給auto_ptr對象托管3.Copy constructor:auto_ptr(const auto_ptr&) throw();template auto_ptr(const auto_ptr& a) throw();指針的托管權會發(fā)生轉移4.Destructor: ~auto_ptr();釋放指針p指向的空間5.提供了兩個成員函數X* get() const throw();//返回保存的指針,對象中仍保留指針X* release() const throw();//返回保存的指針,對象中不保留指針
auto_ptr實現(xiàn)關鍵點1.利用特點”棧上對象在離開作用范圍時會自動析構”2.對于動態(tài)分配的內存,其作用范圍是程序員手動控制的,這給程序員帶來了方便但也不可避免疏忽造成的內存泄漏,畢竟只有編譯器是最可靠的。3.auto_ptr通過在棧上構建一個對象a,對象a中wrap了動態(tài)分配內存的指針p,所有對指針p的操作都轉為對對象a的操作。而在a的析構函數中會自動釋放p的空間,而該析構函數是編譯器自動調用的,無需程序員操心。
多說無益,看一個最實用的例子:
分析:1.如果采用方案1,那么必須考慮到函數在因throw異常的時候釋放所分配的內存。這樣造成的結果是在每個分支處都要很小心的手動 delete pTC;2.如果采用方案2,那就無需操心何時釋放內存,不管foo()因何原因退出,棧上對象pTC的析構函數都將調用,因此托管在之中的指針所指的內存必然安全釋放。注意:
至此,智能指針的優(yōu)點已經很明了了。但是要注意使用中的一個陷阱,那就是指針的托管權是會轉移的。例如在上例中,如果auto_ptr pTC(new TC);auto_ptr pTC1=pTC;那么,pTC1將擁有該指針,而pTC沒有了,如果再用pTC去引用,必然導致內存錯誤。要避免這個問題,可以考慮使用采用了引用計數的智能指針,例如boost::shared_ptr等個人觀點1.vc++庫中的智能指針auto_ptr本不像都像前面介紹的那樣auto_ptr pTC(new TC);auto_ptr pTC1=pTC;其中pTC指針并沒有被托管,其地址還是指向new TC 的。但是并沒有出現(xiàn)同一個指針釋放兩次的問題。2.VC中的 auto_ptr是一個對象,和內置指針是不一樣的,它沒有支持測試智能指針NULL的功能。auto_ptr<TestC> p;if(p == NULL); 并沒有辦法通過編譯。3.并不支持將智能指針轉化為內置指針,如:void print(TestC* p)