1樓:
1全部簡單地說,編譯器生成**的時候,該呼叫哪個成員函式是根據型別判斷的,b的型別是基類指標,編譯器就呼叫基類的成員函式fun1。為什麼是這樣呢?
因為繼承關係下,編譯器允許我們把子類當作基類用,這是合理的,也就是向上型別轉換,把子類的資訊全部丟棄(只是忽略,記憶體中還保留著,可以用靜態轉換static_cast轉換回去,也就是向下型別轉換),因此你把a的地址賦給b時,編譯器把a當作基類用,當然應該和沒有子類的情況一樣,所以呼叫了基類的fun1。那如何才能根據實際的型別而不是先做向上轉換來呼叫成員函式呢?
c++為了解決你這個問題,引入了多型,也就是虛擬函式,在成員函式定義前加上virtual。比如:
#include
class baseclass
為什麼和不加virtual不一樣呢?因為虛擬函式的入口存在了物件的記憶體空間,有一張虛擬函式表,呼叫的時候是去找表找到入口地址後呼叫,因此物件的記憶體是什麼型別就會呼叫什麼型別的虛擬函式,即使向上型別轉換了,虛擬函式表也不會變,照樣呼叫。
2樓:匿名使用者
b指標是baseclass*型別,而派生類的成員函式baseclass::fun1沒有用virtual修飾,對應同簽名(同名同引數列表同返回值,話說iso c++不支援省略函式返回值,lz你把一堆返回值漏了,一般應該編譯不過)的基類成員函式baseclass::fun1也沒有用virtual修飾,即baseclass::
fun1不是虛擬函式,因此b->fun1()會按b指向的物件型別直接呼叫baseclass中定義的函式。如果用virtual修飾fun1(),那麼fun1是虛擬函式,且這個虛擬函式被派生類覆蓋,通過指標或引用呼叫實際型別是派生類的物件的成員函式時,會在執行期動態繫結到派生類中同函式簽名的最終對應覆蓋版本(final overrider)——這裡是derivedclass::fun1,這才是lz所要的效果。
====
[原創回答團]
3樓:匿名使用者
在父類的 fun() 函式前加個 virtual 關鍵字,把函式宣告為虛擬函式即可
核心問題就是沒有用虛擬函式,由此引發的是 動 / 靜態繫結 的問題
虛擬函式無所謂你當前的物件是哪一級父類,他都會在被呼叫時動態的去查詢到最開始的那個類。
如果你的fun函式是虛擬函式,那麼在呼叫時,雖然你已把物件賦給了父類baseclas,但是它會動態的把這個函式繫結到子類derivedclass上,繼而呼叫derivedclass的fun()函式。
b-fun1(); 的輸出將會是:「呼叫派生類的fun1」
如果你沒有用虛擬函式,那麼函式在呼叫時就不會動態的去查詢它原本屬於哪個類,而是直接呼叫當前類,也就是父類bassclass中的fun函式。所以輸出結果會使
「呼叫父類中的fun1」
總結用虛擬函式就會動態繫結,原先是誰的,呼叫的時候還是用誰的
不用虛擬函式就是靜態繫結,不管是誰的,只用現在的。
4樓:匿名使用者
你如果在基類中,把fun1()作為虛擬函式,你就能調子類的方法。
按你現在寫的程式,一定是調基類。你只是在子類中,把fun1()重寫了而已。
c中指向派生類指標問題,C 中指向派生類指標問題
先看兩個知識點 1.c 中基類和派生類遵循型別相容原則 即可用派生類的物件去初始化基類的物件,可用派生類的物件去初始化基類的引用,可用派生類物件的地址去初始化基類物件指標。2.c 中動態繫結條件發生需要滿足2個條件 1 只有指定為虛擬函式的成員函式才能進行動態繫結,成員函式預設為非虛擬函式,非虛擬函...
C基類怎麼呼叫派生類成員,C 的基類如何訪問其派生類的成員變數?
很簡單,在基類來中定義虛函源數,例如函bai數原型為 virtual void printinfo 在類 undergraduate 及 graduate 在 printinfo 中分別du輸出各自zhi 資訊即可。這時dao呼叫基類的 printinfo 函式就可輸出派生類資訊 只需在基類中定ba...
c中基類能用派生類中的成員嗎
不能。派生類可以使用基類的,但基類無法訪問派生類中的成員資料或成員函式。因為基類不可能知道它的派生類有哪些成員資料或函式。不能。不能。不能,只能派生類使用基類的方法 c 中派生類如何使用基類中的資料成員 如果你是派生類例項,這個結果是正確的,派生後會覆蓋基類成員。派生類中繼承了基類的資料成員,只有基...