C++基礎(chǔ)語(yǔ)法梳理:智能指針和強(qiáng)制類型轉(zhuǎn)換運(yùn)算符
本期是C++基礎(chǔ)語(yǔ)法分享的第九節(jié),今天給大家來(lái)分享一下:
(1)智能指針;
(2)強(qiáng)制類型轉(zhuǎn)換運(yùn)算符;
(3)運(yùn)行時(shí)類型信息 (RTTI);

智能指針
C++ 標(biāo)準(zhǔn)庫(kù)(STL)中
頭文件:#include <memory>
C++ 98:
C++ 11:
shared_ptr
unique_ptr
weak_ptr
auto_ptr(被 C++11 棄用)
Class shared_ptr 實(shí)現(xiàn)共享式擁有(shared ownership)概念。多個(gè)智能指針指向相同對(duì)象,該對(duì)象和其相關(guān)資源會(huì)在 “最后一個(gè) reference 被銷毀” 時(shí)被釋放。為了在結(jié)構(gòu)較復(fù)雜的情景中執(zhí)行上述工作,標(biāo)準(zhǔn)庫(kù)提供 weak_ptr、bad_weak_ptr 和 enable_shared_from_this 等輔助類。
Class unique_ptr 實(shí)現(xiàn)獨(dú)占式擁有(exclusive ownership)或嚴(yán)格擁有(strict ownership)概念,保證同一時(shí)間內(nèi)只有一個(gè)智能指針可以指向該對(duì)象。你可以移交擁有權(quán)。它對(duì)于避免內(nèi)存泄漏(resource leak)——如 new 后忘記 delete ——特別有用。
shared_ptr
多個(gè)智能指針可以共享同一個(gè)對(duì)象,對(duì)象的最末一個(gè)擁有著有責(zé)任銷毀對(duì)象,并清理與該對(duì)象相關(guān)的所有資源。
支持定制型刪除器(custom deleter),可防范 Cross-DLL 問(wèn)題(對(duì)象在動(dòng)態(tài)鏈接庫(kù)(DLL)中被 new 創(chuàng)建,卻在另一個(gè) DLL 內(nèi)被 delete 銷毀)、自動(dòng)解除互斥鎖
weak_ptr
weak_ptr 允許你共享但不擁有某對(duì)象,一旦最末一個(gè)擁有該對(duì)象的智能指針失去了所有權(quán),任何 weak_ptr 都會(huì)自動(dòng)成空(empty)。因此,在 default 和 copy 構(gòu)造函數(shù)之外,weak_ptr 只提供 “接受一個(gè) shared_ptr” 的構(gòu)造函數(shù)。
可打破環(huán)狀引用(cycles of references,兩個(gè)其實(shí)已經(jīng)沒(méi)有被使用的對(duì)象彼此互指,使之看似還在 “被使用” 的狀態(tài))的問(wèn)題
unique_ptr
unique_ptr 是 C++11 才開(kāi)始提供的類型,是一種在異常時(shí)可以幫助避免資源泄漏的智能指針。采用獨(dú)占式擁有,意味著可以確保一個(gè)對(duì)象和其相應(yīng)的資源同一時(shí)間只被一個(gè) pointer 擁有。一旦擁有著被銷毀或編程 empty,或開(kāi)始擁有另一個(gè)對(duì)象,先前擁有的那個(gè)對(duì)象就會(huì)被銷毀,其任何相應(yīng)資源亦會(huì)被釋放。
unique_ptr 用于取代 auto_ptr
auto_ptr
被 c++11 棄用,原因是缺乏語(yǔ)言特性如 “針對(duì)構(gòu)造和賦值” 的?std::move?語(yǔ)義,以及其他瑕疵。
auto_ptr 與 unique_ptr 比較
auto_ptr 可以賦值拷貝,復(fù)制拷貝后所有權(quán)轉(zhuǎn)移;unqiue_ptr 無(wú)拷貝賦值語(yǔ)義,但實(shí)現(xiàn)了move?語(yǔ)義;
auto_ptr 對(duì)象不能管理數(shù)組(析構(gòu)調(diào)用?delete),unique_ptr 可以管理數(shù)組(析構(gòu)調(diào)用?delete[]?);
強(qiáng)制類型轉(zhuǎn)換運(yùn)算符
static_cast
用于非多態(tài)類型的轉(zhuǎn)換
不執(zhí)行運(yùn)行時(shí)類型檢查(轉(zhuǎn)換安全性不如 dynamic_cast)
通常用于轉(zhuǎn)換數(shù)值數(shù)據(jù)類型(如 float -> int)
可以在整個(gè)類層次結(jié)構(gòu)中移動(dòng)指針,子類轉(zhuǎn)化為父類安全(向上轉(zhuǎn)換),父類轉(zhuǎn)化為子類不安全(因?yàn)樽宇惪赡苡胁辉诟割惖淖侄位蚍椒ǎ?/p>
向上轉(zhuǎn)換是一種隱式轉(zhuǎn)換。
dynamic_cast
用于多態(tài)類型的轉(zhuǎn)換
執(zhí)行行運(yùn)行時(shí)類型檢查
只適用于指針或引用
對(duì)不明確的指針的轉(zhuǎn)換將失?。ǚ祷?nullptr),但不引發(fā)異常
可以在整個(gè)類層次結(jié)構(gòu)中移動(dòng)指針,包括向上轉(zhuǎn)換、向下轉(zhuǎn)換
const_cast
用于刪除 const、volatile 和 __unaligned 特性(如將 const int 類型轉(zhuǎn)換為 int 類型 )
reinterpret_cast
用于位的簡(jiǎn)單重新解釋
濫用 reinterpret_cast 運(yùn)算符可能很容易帶來(lái)風(fēng)險(xiǎn)。 除非所需轉(zhuǎn)換本身是低級(jí)別的,否則應(yīng)使用其他強(qiáng)制轉(zhuǎn)換運(yùn)算符之一。
允許將任何指針轉(zhuǎn)換為任何其他指針類型(如?char*?到?int*?或?One_class*?到?Unrelated_class*?之類的轉(zhuǎn)換,但其本身并不安全)
也允許將任何整數(shù)類型轉(zhuǎn)換為任何指針類型以及反向轉(zhuǎn)換。
reinterpret_cast 運(yùn)算符不能丟掉 const、volatile 或 __unaligned 特性。
reinterpret_cast 的一個(gè)實(shí)際用途是在哈希函數(shù)中,即,通過(guò)讓兩個(gè)不同的值幾乎不以相同的索引結(jié)尾的方式將值映射到索引。
bad_cast
由于強(qiáng)制轉(zhuǎn)換為引用類型失敗,dynamic_cast 運(yùn)算符引發(fā) bad_cast 異常。
bad_cast 使用
運(yùn)行時(shí)類型信息 (RTTI)
dynamic_cast
用于多態(tài)類型的轉(zhuǎn)換
typeid
typeid 運(yùn)算符允許在運(yùn)行時(shí)確定對(duì)象的類型
type_id 返回一個(gè) type_info 對(duì)象的引用
如果想通過(guò)基類的指針獲得派生類的數(shù)據(jù)類型,基類必須帶有虛函數(shù)
只能獲取對(duì)象的實(shí)際類型
type_info
type_info 類描述編譯器在程序中生成的類型信息。 此類的對(duì)象可以有效存儲(chǔ)指向類型的名稱的指針。 type_info 類還可存儲(chǔ)適合比較兩個(gè)類型是否相等或比較其排列順序的編碼值。 類型的編碼規(guī)則和排列順序是未指定的,并且可能因程序而異。
頭文件:typeinfo
typeid、type_info 使用
今天的分享就到這里了,大家要好好學(xué)C++喲~
寫(xiě)在最后:對(duì)于準(zhǔn)備學(xué)習(xí)C/C++編程的小伙伴,如果你想更好的提升你的編程核心能力(內(nèi)功)不妨從現(xiàn)在開(kāi)始!
微信公眾號(hào):C語(yǔ)言編程學(xué)習(xí)基地
整理分享(多年學(xué)習(xí)的源碼、項(xiàng)目實(shí)戰(zhàn)視頻、項(xiàng)目筆記,基礎(chǔ)入門(mén)教程)
歡迎轉(zhuǎn)行和學(xué)習(xí)編程的伙伴,利用更多的資料學(xué)習(xí)成長(zhǎng)比自己琢磨更快哦!
