C 多重繼承的指標問題

2021-12-30 02:56:03 字數 1577 閱讀 3484

下面說說c++多重繼承中關於指標的一些問題。

指標指向問題

先看下面的程式:

class base1;};

class base2;};

class derive : public base1, public base2

virtual void fun2 ()

};int main()

我電腦上的執行結果:

首先,可以看到&od和pb1指標指向相同的儲存位址。為什麼?

這是因為當我們new乙個derive類的時候,計算機給derive類分配的空間可以分為三部分:首先是類base1的部分,然後是base2的部分,然後是derive中除去base和base2剩餘部分,如下圖。

base1

base2

derive

所以&od肯定儲存的是整體的首位址,而pb1指向的是base1的首位址,恰好也是整體的首位址,所以有&od和pb1的值剛好相等。pb2則指向的是base2的首位址。

可是後面為什麼會有&od == pb2呢?這是因為當編譯器發現乙個指向派生類的指標和指向其某個基類的指標進行==運算時,會自動將指標做隱式型別提公升已遮蔽多重繼承帶來的指標差異。因為兩個指標做比較,目的通常是判斷兩個指標是否指向了同乙個記憶體物件例項,在上面的場景中,&od和pb2雖然指標值不等,但是他們確確實實都指向了同乙個記憶體物件(即new derive產生的記憶體物件)。

指標型別轉換問題

還是使用上面的類,看主函式:

int main()

猜猜執行結果:

是不是很意外,為什麼pb2->fun2()的結果是derive::fun1。這裡我們看到的是使用強制型別轉換是不能把base1型別的指標轉成base2型別的指標的,必須使用dynamic_cast的形式進製轉換才奏效。

下面我們探索下為什麼輸出的是derive::fun1。

我們修改base1的定義:

class base1

; virtual void fun1() ;

};給新增乙個函式fun3,然後再次執行上面的main函式,結果如下:

我們可以發現強制轉換不會成功,也不會報錯,你呼叫base2的fun2函式,因為強制轉換不成功,所以指標仍然指向base1,而base1中沒有fun2,所以就會自動呼叫宣告的函式中的第乙個函式。(不知道為什麼會這樣設計!)

上面強制將base1轉為base2不會報錯,但是不能執行處正確結果。而我們強制將base2轉為base1呢?

int main()

這樣程式執行到第6行的時候會直接奔潰。

所以:1. c++多重繼承需要慎用

2. 型別轉換盡量採用c++內建的型別轉換函式,而不要強行轉換。

C 多重繼承與void 指標轉換問題

c 支援多重繼承,然而多重繼承可能會導致一些奇怪的問題,我前段時間遇到乙個指標轉換問題,非常典型。先看乙個簡單的測試 include using namespace std class ia virtual void a 0 class ib virtual void b 0 class cmult...

C 在多重繼承時的指標轉換問題

在c 中,指標的型別轉換是經常發生的事情,比如將派生類指標轉換為基類指標,將基類指標轉換為派生類指標。指標的本質其實就是乙個整數,用以記錄程序虛擬記憶體空間中的位址編號,而指標的型別決定了編譯器對其指向的記憶體空間的解釋方式。基於上面的理解,我們似乎可以得出乙個結論,c 中對指標進行型別轉換,不會改...

多重繼承 C 中的多重繼承

多重繼承是c 的一項功能,其中乙個類可以從多個類繼承。繼承類的建構函式以它們繼承的相同順序被呼叫。例如,在以下程式中,在a的建構函式之前呼叫b的建構函式。include using namespace std class a class b class c public b,public a not...