C 智慧型指標

2021-07-11 23:36:16 字數 2688 閱讀 3392

智慧型指標是乙個類。

對指標指向的類進行引用計數,在智慧型指標的建構函式處對引用數+1,在析構函式處對引用數-1,當引用計數為0時進行delete。

public:

operator t*()

t& operator*()

t* operator->()

private:

t* p;

auto_ptr是現在標準庫裡面乙個輕量級的智慧型指標的實現,存在於標頭檔案 memory中,之所以說它是輕量級,是因為它只有乙個成員變數(擁有物件的指標),相關的呼叫開銷也非常小。

auto_ptr的使用很簡單,通過建構函式擁有乙個動態分配物件的所有權,然後就可以被當作物件指標來使用,當auto_ptr物件被銷毀的時候,它也會自動銷毀自己擁有所有權的物件(嗯,標準的raai做法),release可以用來手動放棄所有權,reset可用於手動銷毀內部物件。

但實際上,auto_ptr是乙個相當容易被誤用並且在實際中常常被誤用的類。原因是由於它的物件所有權占用的特性和它非平凡的拷貝行為。

auto_ptr的物件所有權是獨占性的!

這決定了不可能有兩個auto_ptr物件同時擁有同一動態物件的所有權,從而也導致了auto_ptr的拷貝行為是非對等的,其中伴隨著物件所有權的轉移。

同時也不要將auto_ptr放進標準庫的容器中,否則在標準庫容器無準備的拷貝行為中(標準庫容器需要的拷貝行為是等價的),會導致難以發覺的錯誤。

auto_ptr特殊的拷貝行為使得使用它來遠距離傳遞動態物件變成了一件十分危險的行為,在傳遞的過程中,一不小心就會留下一些實際為空但程式本身卻缺少這樣認知的auto_ptr物件。

簡單的說來,auto_ptr適合用來管理生命週期比較短或者不會被遠距離傳遞的動態物件,使用auto_ptr來管理動態分配物件,最好是侷限於某個函式內部或者是某個類的內部。也就是說,動態物件的產生,使用和銷毀的全過程是處於乙個小的受控的範圍,而不會在其中加入一些適應未來時態的擴充套件。

auto_ptr的幾點注意事項:

auto_ptr不能共享所有權

auto_ptr不能指向陣列

auto_ptr不能作為容器的成員

不能通過複製操作來初始化auto_ptr

std::auto_ptr p(new int(42)); //ok

std::atuo_ptrp = new int(42);//error

這是因為auto_ptr的建構函式被定義了explicit

不要把auto_ptr放入容器

shared_ptr是boost庫所提供的乙個智慧型指標的實現,正如其名字所蘊意的一樣:

an important goal of shared_ptr is to provide a standard shared-ownership pointer.

shared_ptr的乙個重要目的就是為了提供乙個標準的共享所有權的智慧型指標。

—— boost庫文件

沒錯,shared_ptr就是為了解決auto_ptr在物件所有權上的侷限性(auto_ptr是獨佔的),在使用引用計數的機制上提供了可以共享所有權的智慧型指標,當然這不會沒有任何額外的代價……

首先乙個shared_ptr物件除了包括乙個所擁有物件的指標(px)外,還必須包括乙個引用計數**物件(shared_count)的指標(pn)。而這個引用計數**物件包括乙個真正的多型的引用計數物件(sp_counted_base)的指標(_pi),真正的引用計數物件在使用vc編譯器的情況下包括乙個虛表,乙個虛表指標,和兩個計數器。

shared_ptr是一種智慧型指標(smart pointer)。shared_ptr的作用有如同指標,但會記錄有多少個shared_ptrs共同指向乙個物件。

這便是所謂的引用計數(reference counting)。一旦最後乙個這樣的指標被銷毀,也就是一旦某個物件的引用計數變為0,這個物件會被自動刪除。這在非環形資料結構中防止資源洩露很有幫助。

auto_ptr由於它的破壞性複製語義,無法滿足標準容器對元素的要求,因而不能放在標準容器中;如果我們希望當容器析構時能自動把它容納的指標元素所指的物件刪除時,通常採用一些間接的方式來實現,顯得比較繁瑣。boost庫中提供了一種新型的智慧型指標shared_ptr,它解決了在多個指標間共享物件所有權的問題,同時也滿足容器對元素的要求,因而可以安全地放入容器中。

weak_ptr是為配合shared_ptr而引入的一種智慧型指標來協助shared_ptr工作,它可以從乙個shared_ptr或另乙個weak_ptr物件構造,它的構造和析構不會引起引用記數的增加或減少。沒有過載*和->但可以使用lock獲得乙個可用的shared_ptr物件

標頭檔案: 「boost/scoped_ptr.hpp」

boost::scoped_ptr 用於確保動態分配的物件能夠被正確地刪除。scoped_ptr 有著與std::auto_ptr類似的特性,而最大的區別在於它不能轉讓所有權而auto_ptr可以。事實上,scoped_ptr永遠不能被複製或被賦值!scoped_ptr 擁有它所指向的資源的所有權,並永遠不會放棄這個所有權。scoped_ptr的這種特性提公升了我們的**的表現,我們可以根據需要選擇最合適的智慧型指標(scoped_ptr 或 auto_ptr)。

要決定使用std::auto_ptr還是boost::scoped_ptr, 就要考慮轉移所有權是不是你想要的智慧型指標的乙個特性。如果不是,就用scoped_ptr. 它是一種輕量級的智慧型指標;使用它不會使你的程式變大或變慢。它只會讓你的**更安全,更好維護。

c 智慧型指標

auto prt 它是 它所指向物件的擁有者 所以當自身物件被摧毀時候,該物件也將遭受摧毀,要求乙個物件只有乙個擁有者,注意 auto prt 不能使用new 來分配物件給他 include include using namespace std template void bad print au...

c 智慧型指標

很久沒寫部落格了,不知道如何表達了,哈哈.我先介紹一下深淺拷貝.class copy 此時a.ptr和b.ptr指向同乙個物件,當我們delete a.ptr時 b.ptr所指向的物件已經不存在了,要是我們引用b.ptr指向的物件也就會出問題了.深拷貝 把a.ptr所指向的物件拷貝乙份給b.ptr ...

c 智慧型指標

記得前不久有一次面試被問到智慧型指標的實現,當時對智慧型指標只是聽說但沒有了解過,就亂七八糟地說了一遍。今天寫了一遍智慧型指標,用了引用計數的概念。主要思想就是,用乙個新類對原本需要的型別進行了一層封裝,這個新類中儲存了原本的物件指標和乙個引用計數的指標,之所以全部用指標來儲存,就是因為會出現多個新...