(1)dynamic_cast轉化,實現安全向下進行轉化,那麼實際上,根據vptr的指向,vtable中對應虛函式位址繫結的物件,來進行檢測以及轉化為實際的物件型別。那麼關於dynamic_cast,我們必須意識到,最關鍵的點在於虛表,這是多型內容中最重要的部分。那麼對於不同繼承情況下的物件布局,已經總結過了,或者看上面的鏈結也行。那麼在這篇中,重點放在typeid運算子,這個又是怎麼實現動態檢測的呢?(2)typeid操作符,返回指標或者引用所指物件的實際型別。
class type_info
;
從上面的定義也可以看到,type_info提供了兩個物件的相等比較操作,但是使用者並不能自己定義乙個type_info的物件,而只能通過typeid運算子返回乙個物件的const引用來使用type_info的物件。因為其只宣告了乙個建構函式(複製建構函式)且為private,所以編譯器不會合成任何的建構函式,而且賦值操作執行符也為private。這兩個操作就完全禁止了使用者對type_info物件的定義和複製操作,使用者只能通過指向type_info的物件的指標或引用來使用該類。
1)typeid識別靜態型別
當typeid中的運算元是如下情況之一時,typeid運算子指出運算元的靜態型別,即編譯時的型別。
(1)型別名
(2)乙個基本型別的變數
(3)乙個具體的物件
(4)乙個指向不含有virtual函式的類物件的指標的解引用
(5)乙個指向不含有virtual函式的類物件的引用
靜態型別在程式的執行過程中並不會改變,所以並不需要在程式執行時計算型別,在編譯時就能根據運算元的靜態型別,推導出其型別資訊。例如如下的**片斷,typeid中的運算元均為靜態型別:
class x ;
class xx : public x ;
class y ;
int main()
2)typeid識別多型型別當typeid中的運算元是如下情況之一時,typeid運算子需要在程式執行時計算型別,因為其其運算元的型別在編譯時期是不能被確定的。
(1)乙個指向含有virtual函式的類物件的指標的解引用
(2)乙個指向含有virtual函式的類物件的引用
多型的型別是可以在執行過程中被改變的,例如,乙個基類的指標,在程式執行的過程中,它可以指向乙個基類物件,也可以指向該基類的派生類的物件,而typeid運算子需要在執行過程中識別出該基類指標所指向的物件的實際型別,這就需要typeid運算子在執行過程中計算其指向的物件的實際型別。例如對於以下的類定義:
class x
virtual void vfunc()
private:
int mx;
};class xx : public x
virtual void vfunc()
private:
int mxx;
};
測試**如下:
void printtypeinfo(const x *px)
int main()
無論printtypeinfo函式中指標px指向的物件是基類x的物件,還是指向派生類xx的物件,typeid執行返回的px的型別資訊都是相同的,因為px為乙個靜態型別,其型別名均為px1x。但是typeid運算子卻能正確地計算出了px指向的物件的實際型別。
多型型別是通過在類中宣告乙個或多個virtual函式來區分的。因為在c++中,乙個具備多型性質的類,正是內含直接宣告或繼承而來的virtual函式。多型類的物件的型別資訊儲存在虛函式表的索引的-1的項中,該項是乙個type_info物件的位址,該type_info物件儲存著該物件對應的型別資訊,每個類都對應著乙個type_info物件。下面就對這一說法進行驗證。
先來看《深度探索c++物件模型中》
typedef void (*funcptr)();
int main()
上面,vptr指向的vtable中的位置,仍然是第乙個虛函式的位址,索引-1才是type_info的位址資訊!在多重繼承和虛擬繼承的情況下,乙個類有n(n>1)個虛函式表,該類的物件也有n個vptr,分別指向這些虛函式表,但是乙個類的所有的虛函式表的索引為-1的項的值(type_info物件的位址)都是相等的,即它們都指向同乙個type_info物件,這樣就實現了無論使用了哪乙個基類的指標或引用指向其派生類的物件,都能通過相應的虛函式表獲取到相同的type_info物件,從而得到相同的型別資訊。
所以,真正的布局畫圖,如果更正為下面這樣,更好:
C 多型和物件的記憶體布局 一
在當前工程右鍵 屬性 先選擇左側的c c 命令列,然後在其他選項這裡寫上 d1 reportallclasslayout,它可以看到所有相關類的記憶體布局,如果寫上 d1 reportsingleclasslayout 為類名 則只會打出指定類 的記憶體布局。成員變數是按照定義的順序來儲存的,最先宣...
C 多型和物件的記憶體布局 二
程式輸出 sizeof base 1 12 成員屬性 指向虛函式表的指標 sizeof derive 1 20 base成員屬性 derive成員屬性 指向虛函式表的指標 base記憶體布局 1 class base 1 size 12 1 1 0 1 4 base1 1 1 8 base1 2 1...
從記憶體上解析c 中陣列為什麼不支援多型
前段時間在c c 版塊的時候,看到有人問為什麼陣列物件不支援多型的問題,當時沒有回,只是感覺不支援!不能拿出理論和實際證據!後面因為工作也就沒有 細想,今天剛好看到酷殼上陳皓老師說的也就來述說一下!因為這個涉及到記憶體的問題,所以 我們先來乙個小段c語言簡單 typedef struct base ...