第18章 特殊工具與技術 6

2021-06-03 00:51:42 字數 1592 閱讀 8060

18.2 執行時型別識別

通過執行時型別識別(rtti),程式能夠使用基類的指標或引用來檢索這些指標或引用所指物件的實際派生型別。

通過下面兩個操作符提供rtti:

(1) typeid操作符,返回指標或引用所指物件的實際型別。

(2) dynamic_cast操作符,將基類型別的指標或引用安全地轉換為派生型別的指標或引用。

這些操作符只為帶有乙個或多個虛函式的類返回動態型別資訊,對於其他型別,返回靜態(即編譯時)型別的資訊。

對於帶虛函式的類,在執行時執行rtti操作符,但對於其他型別,在編譯時計算rtti操作符。

從基類指標獲得派生型別為最好的方法是通過虛函式。當使用虛函式的時候,編譯器自動根據物件的實際型別選擇正確的函式。

使用動態強制型別轉換要小心。只要有可能,定義和使用虛函式比直接接管型別管理好得多。

18.2.1 dynamic_cast操作符

可以使用dynamic_cast操作符將基類型別物件的引用或指標轉換為同一繼承層次中其他型別的引用或指標。與dynamic_cast一起使用的指標必須是有效的——它必須為0或者指向乙個物件。

與其他強制型別轉換不同,dynamic_cast涉及執行時型別檢查。如果繫結到引用或指標的物件不是目標型別物件,則dynamic_cast失敗。如果轉換到指標型別的dynamic_cast失敗,則dynamic_cast的結果是0值;如果轉換到引用型別的dynamic_cast失敗,則丟擲乙個bad_cast型別的異常。

因此,dynamic_cast操作符一次執行兩個操作。它首先驗證被請求的轉換是否有效,只有轉換有效,操作符才實際進行轉換。一般而言,引用或指標所繫結的物件的型別在編譯時是未知的,基類的指標可以賦值為指向派生類物件,同樣,基類的引用也可以用派生類物件初始化,因此,dynamic_cast操作符執行的驗證必須在執行時進行。

1. 使用dynamic_cast操作符

可以對值為0的指標應用dynamic_cast,這樣做的結果是0。

繼承不代表有多型性,繼承只是多型性的乙個前提條件。

dynamic_cast需要具有多型性的類才能進行轉換。

virtual function是保證多型性的條件。

如果沒有virtual,即使是有繼承關係的型別之間,也不能使用dynamic_cast進行轉換。

vs報出的編譯錯誤很直接的:type is not polymorphic

base1 *ba=new child1();

child1 *c=dynamic_cast(ba);

class base1

};class child1:public base1

};

2. 使用dynamic_cast和引用型別

也可以使用dynamic_cast將基類引用轉換為派生類引用。

因為不存在空引用,所以不可能使用用於指標強制型別轉換的檢查策略,相反,當轉換失敗的時候,它丟擲乙個std::bad_cast異常,該異常在庫標頭檔案typeinfo中定義。

child1 ba=child1();

base1 &b=ba;

trycatch(bad_cast)

第18章 特殊工具與技術 4

18.1.6 類特定的new和delete 編譯器看到類型別的new或delete表示式的時候,它檢視該類是否有operator new或operator delete成員,如果類定義 或繼承 了自己的成員new和delete函式,則使用那些函式為物件分配和釋放記憶體 否則,呼叫這些函式的標準庫版本...

第18章 特殊工具與技術 5

18.2 執行時型別識別 通過執行時型別識別 rtti 程式能夠使用基類的指標或引用來檢索這些指標或引用所指物件的實際派生型別。通過下面兩個操作符提供rtti 1 typeid操作符,返回指標或引用所指物件的實際型別。2 dynamic cast操作符,將基類型別的指標或引用安全地轉換為派生型別的指...

第18章 特殊工具與技術 1

18.1 優化記憶體分配 c 的記憶體分配是一種型別化操作 new為特定型別分配記憶體,並在新分配的記憶體中構造該型別的乙個物件。new表示式自動執行合適的建構函式來初始化每個動態分配的類型別。18.1.1 c 中的記憶體分配 c 中,記憶體分配和物件構造緊密糾纏,就像析構和記憶體 一樣。使用new...