智能指針

一、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++來說,由於沒有垃圾回收機制,內存泄漏對每一個程序員來說都是一個非常頭痛的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章