一、std::auto_ptr
1、auto_ptr的構造函數接受原始指針作爲參數,雖然它是一個對象,但是重載了operator*和operator->,可以把它用在大多數普通指針可用的地方。當退出作用域時,auto_ptr對象的析構函數會釋放原始指針。
例:
int main
{
auto_ptr<ClassA> p(new ClassA);
}
二、boost::scoped_ptr
1、scoped_ptr類摘要:
2、scoped_ptr的構造函數接受一個類型爲T*的指針p,創建一個scoped_ptr對象,並在內部保存指針參數p。當scoped_ptr對象的生命期結束時,析構函數會自動銷燬保存的指針對象。
3、boost::scoped_ptr和std::auto_ptr類似,但有不同
兩者都不能作爲容器的元素。
auto_ptr對指針的所有權是獨佔性的,在auto_ptr的複製構造函數內部,最後會將被拷貝對象內部的指針釋放掉。
scoped_ptr不支持拷貝和賦值,拒絕了指針所有權的轉讓。
三、boost::shared_ptr
1、shared_ptr類摘要
2、shared_ptr與scoped_ptr一樣包裝了new操作符在堆上分配的動態對象,但它實現的是引用計數型的智能指針,可以被自由地拷貝和賦值,當引用計數爲0時,它才刪除被包裝的動態分配的對象。shared_ptr可以安全地放到標準容器中使用。
3、shared_ptr使用中應該注意:
(1)不要將對象的內存交給兩個shared_ptr管理。
(2)避免對shared_ptr所管理的對象的直接內存管理操作,以免造成該對象的重釋放。
(3)不要構造一個臨時的shared_ptr作爲函數的參數。
(4)shared_ptr作爲函數參數傳遞的時候可以採用引用,節省開銷。
(5)不能將T*直接賦值給一個智能指針。
(6)不能寫ptr = NULL,應該使用ptr.reset()。
*4、擴展
explicit關鍵字作用:只對構造函數起作用,用來抑制隱式轉換。
四、boost::weak_ptr
1、boost::weak_ptr類摘要:
2、weak_ptr被設計爲與shared_ptr共同工作,可以從一個shared_ptr或者另一個weak_ptr對象構造,獲得資源的觀測權。但weak_ptr沒有共享資源,它的構造不會引起指針引用計數的增加,析構時也不會導致引用計數的減少。它可以使用lock()函數從被觀測的shared_ptr獲得一個可用的shared_ptr對象,從而操作資源。但當expired()==true的時候,lock()將返回一個存儲空指針的shared_ptr。
3、weak_ptr一般用來打破循環引用所帶來的內存泄漏,例如下例:
class Teacher
{
public:
shared_ptr<Student> m_pStudent;
};
class Student
{
public:
shared_ptr<Teacher> m_pTeacher;
};
int main()
{
shared_ptr<Teacher> pTeacher(new Teacher);
shared_ptr<Student> pStudent(new Student);
pTeacher->m_pStudent = pStudent;
pStudent->m_pTeacher = pTeacher;
}
由於Teacher和Student的循環引用,在退出main函數後,pTeacher和pStudent的引用計數都不爲0,造成內存泄漏。可以使用weak_ptr來解決這個問題。
class Student
{
public:
weak_ptr<Teacher> m_pTeacher;
}
3、最後值得一提的是,雖然通過弱引用指針可以有效的解除循環引用,但這種方式必須在程序員能預見會出現循環引用的情況下才能使用,也可以是說這個僅僅是一種編譯期的解決方案,如果程序在運行過程中出現了循環引用,還是會造成內存泄漏的。因此,不要認爲只要使用了智能指針便能杜絕內存泄漏。畢竟,對於C++來說,由於沒有垃圾回收機制,內存泄漏對每一個程序員來說都是一個非常頭痛的問題。