C 智慧型指標的問題

2021-08-03 09:21:46 字數 3467 閱讀 1800

如何回答c++面試中關於智慧型指標的問題?

1、  

什麼是智慧型指標?

2、  

分析下常見的智慧型指標有哪些? 3

、實現乙個智慧型指標唄?

(沒具體說寫哪個,建議預設寫:unique_ptr)

1

、答:智慧型指標(smart pointer)是儲存指向動態分配(堆)物件指標的類,用於生存期控制,能夠確保自動正確的銷毀動態分配的物件,防止記憶體洩露(利用自動呼叫類的析構函式來釋放記憶體)。它的一種通用實現技術是使用引用計數(除此之外還有資源獨佔,如(auto_ptr),只引用,不計數(weak_ptr))。智慧型指標類將乙個計數器與類指向的物件相關聯,引用計數跟蹤該類有多少個物件共享同一指標。每次建立類的新物件時,初始化指標並將引用計數置為1;當物件作為另一物件的副本而建立時,拷貝建構函式拷貝指標並增加與之相應的引用計數;對乙個物件進行賦值時,賦值操作符減少左運算元所指物件的引用計數(如果引用計數為減至0,則刪除物件),並增加右運算元所指物件的引用計數;呼叫析構函式時,建構函式減少引用計數(如果引用計數減至0,則刪除基礎物件)。

2

、常見的智慧型指標以及解析:

auto_ptr

(1)它是c++標準庫提供的類模板,auto_ptr物件通過初始化指向由new建立的動態記憶體,它是這塊記憶體的擁有者,一塊記憶體不能同時被分給兩個擁有者(資源獨佔)。當auto_ptr物件生命週期結束時,其析構函式會將auto_ptr物件擁有的動態記憶體自動釋放。

(2)auto_ptr不能指向陣列,因為auto_ptr在析構的時候只是呼叫delete,而陣列應該要呼叫delete。(但uniquearray管理的是一段連續的空間,它也是防拷貝的,功能類似於vector。)

(3)auto_ptr不能作為容器物件,因為它不支援拷貝構造與賦值(出錯了也不容易發現),stl容器中的元素經常要支援拷貝,賦值等操作,在這過程中auto_ptr會傳遞所有權,那麼就會出錯。

unique_ptr

它是( c++

11引入的,前身是scoped_ptr,scoped_ptr是boost庫里的),也不支援拷貝構造和賦值,但比auto_ptr好,直接賦值會編譯出錯(與auto_ptr最大的不同就是類內私有的宣告了拷貝建構函式和賦值運算子過載,是針對auto_ptr的缺點而出現的)。

shared_ptr

c++11或boost的shared_ptr,基於引用計數的智慧型指標。可隨意賦值,直到記憶體的引用計數為0的時候這個記憶體會被釋放。環狀的鏈式結構可能會形成記憶體洩露(迴圈引用)

迴圈引用問題

(常問到哦)

為了解決類似這樣的問題,c++11引入了weak_ptr,來打破這種迴圈引用。

weak_ptr

c++11或boost的weak_ptr,弱引用。 引用計數有乙個問題就是互相引用形成環,這樣兩個指標指向的記憶體都無法釋放。需要手動打破迴圈引用或使用weak_ptr。顧名思義,weak_ptr是乙個弱引用,它是為了配合shared_ptr而引入的一種智慧型指標,它指向乙個由shared_ptr管理的物件而不影響所指物件的生命週期,也就是說,它只引用,不計數。如果一塊記憶體被shared_ptr和weak_ptr同時引用,當所有shared_ptr析構了之後,不管還有沒有weak_ptr引用該記憶體,記憶體也會被釋放。所以weak_ptr不保證它指向的記憶體一定是有效的,在使用之前需要檢查weak_ptr是否為空指標。

weak_ptr並沒有過載operator->和operator *操作符,因此不可直接通過weak_ptr使用物件,典型的用法是呼叫其lock函式來獲得shared_ptr示例,進而訪問原始物件。

auto_ptr

的實現template

t>

class

autoptr

//採用資源的轉移方法管理記憶體,在它的拷貝構造和賦值運算子引起會出現問題

autoptr(autoptr

&ap)

:ptr(ap.ptr)

autoptr

&operator=(autoptr

&ap)

ptr= ap.ptr;

ap.ptr= null;

}return*this;

}t* operator*()

t* operator->()

voidget_ptr()

~autoptr()

}private:

t*ptr;

};voidfuntest()

//ap3

的ptr

指向的空間,所以沒法向

ap3賦值

int main()

unique_ptr

的實現template

t>

class

unique_ptr

//前身是

scoped_pt

,實現粗暴

—>

禁止轉移

-->

獨佔資源(只允許乙個指標管理資源) //

(禁止調拷貝構造和賦值運算子)

,它只能管理單個物件

t* operator*()

t* operator->()

voidget_ptr()

~unique_ptr ()

}private:

unique_ptr (unique_ptr

&ap);//

禁止拷貝構造

unique_ptr

&operator=(unique_ptr

&ap1);//

禁止賦值

t*ptr;

};//

為什麼unique_ptr

防拷貝的實現必須是私有的宣告? 1

、只給共有的宣告,不給定義。(使用者可以在類外重新給出定義) 2

、只給私有的定義(但是類內可以調拷貝構造和賦值運算子)

所以採用私有的宣告拷貝建構函式和賦值運算子過載函式實現

unique_ptr

的防拷貝

shared_ptr

的實現template

t>

class

share_ptr }

share_ptr(const

share_ptr

&ps)

:_p(ps._p)

,_pcount(ps._pcount)

}t* operator*()

t* operator->()

voidget_ptr()

~share_ptr()

}private:

t* _p;

int*_pcount;

};voidfuntest()

c 智慧型指標的問題 智慧型指標初探(一)

為什麼要有智慧型指標 在c 中,動態記憶體的管理一般是用一對運算子完成的 new和delete。new 在動態記憶體中為物件分配一塊空間並返回乙個指向該物件的指標。delete 指向乙個動態獨享的指標,銷毀物件,並釋放與之關聯的記憶體。使用new和delete動態記憶體管理經常會出現問題 忘記釋放記...

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 ...