面試c++工程師碰到虛函式題目的概率為99%,昨天面試又碰到乙個更經典的問題,先將這些整理,大家共同學習。
#include using namespace std;
class base
void sonaf2(sona *s1)
void refersonaf3(base &rs1)
int main()
可以先試著把輸出結果寫出來,看看與執行結果是否相同。
對應輸出如下:
#include using namespace std;
class base
void sonaf2(sona *s1)
void refersonaf3(base &rs1)
int main()
具體輸出結果如下:
call base virfun2()
construct base object
call base virfun2()
construct base object
construct sona object
call base virfun2()
construct base object
construct sona object
call base virfun2()
construct base object
construct sona object
call base virfun2()
construct base object
construct sona object
call base fun1()
call base virfun2()
call sona fun1()
call base virfun2()
call base fun1()
call sona virfun2()
call sona fun1()
call sona virfun2()
call base fun1()
call sona virfun2()
call base fun1()
call base virfun2()
call base fun1()
call sona virfun2()
call base fun1()
call base virfun2()
call base fun1()
call sona virfun2()
call base fun1()
call sona virfun2()
call sona fun1()
call base virfun2()
call sona fun1()
call sona virfun2()
call sona fun1()
call sona virfun2()
call base fun1()
call sona virfun2()
destruct base object
destruct base object
destruct sona object
destruct base object
destruct sona object
destruct base object
destruct base object
destruct sona object
destruct base object
process returned 0 (0x0) execution time : 0.703 s
press any key to continue.
q1:base *bps = new sona; 後呼叫了父類的建構函式,建構函式裡呼叫的virfun2()又是虛函式,為什麼沒有呼叫子類的virfun2()而是呼叫父類的virfun2()?
r1:因為建立子物件時,是先呼叫父類建構函式再呼叫子類建構函式,所以此時還沒有呼叫子類的建構函式,無法找到子類指向虛函式表的虛指標(乙個類若是有虛函式,那麼物件將會在前四個位元組儲存指向虛函式表的指標,虛函式表存放的是虛函式位址)
q2:base bo = sao;這裡居然沒有輸出?
r2:這裡呼叫的是base類預設的拷貝建構函式而不是我們重寫的無參建構函式。
q3:強制型別轉換是怎麼玩的?
r3:定義乙個父類物件,將該父類物件的指標強制型別轉換為子類指標,並賦給乙個子類指標,則:該子類指標將指向該父類物件,但是其this指標仍然是指向子類的指標。
當該指標呼叫虛成員函式時,將按照物件的記憶體布局(指向虛函式表的指標(儲存在該物件的前四個位元組))呼叫父類虛成員函式。
當該指標呼叫普通成員函式時,將通過this指標呼叫位於**段的該子類的成員函式。
q4:怎麼不是先析構子類嗎?和想的不一樣?
r4:問題就出在了析構函式沒有定義為虛函式,當析構函式沒有定義為虛函式時,就好比我們的fun1()沒有用虛函式一樣,無法呼叫到子類的析構函式。只要定義析構函式為虛函式那麼就可以先輸出destruct sona object。我想這也是一般要求析構函式定義為虛函式的原因吧。
總結:1、對於一般函式,呼叫的哪個類的函式和指標最後的型別一致。
比如:
((sona*)bpb)->fun1();
//call sona fun1()//q3
2、對於虛函式,在於物件例項化時是哪種型別,和指標當前的型別沒有必然關係,並且強制轉換指標型別不改變輸出結果。
base *bps = new sona();
bps->virfun2();
//call sona virfun2()//最常見的,也是傳說中的,多型
((sona*)bps)->virfun2();//強制轉換對虛函式沒有改變,所以之前是sona的,現在還是。
3、物件的引用和指標的效果相同。base &referbo = sao;
referbo.virfun2();//引用的效果和指標的效果相同哦
//call sona virfun2()
虛基類,抽象類,虛函式,純虛函式,virtual
虛基類 在說明其作用前先看一段 class a class b public a class b virtual public a 大家以為這段 的輸出結果是什麼?有的人可能會馬上回答funprint of class a 與 funprint of class b 因為第一次輸出是引用類a的實 例...
virtual 虛函式
virtual 虛函式 下面是對c 的虛函式這玩意兒的理解。一,什麼是虛函式 如果不知道虛函式為何物,但有急切的想知道,那你就應該從這裡開始 簡單地說,那些被virtual關鍵字修飾的成員函式,就是虛函式。虛函式的作用,用專業術語來解釋就是實現多型性 polymorphism 多型性是將介面與實現進...
虛函式(virtual)
上面提到動態多型主要通過虛函式機制實現,這裡介紹以下虛函式。和普通的函式宣告方式相同,只要在函式的返回值前加上virtual關鍵字,該函式就為虛函式,即virtual 函式型別 函式名 形式引數 虛函式的作用 允許通過基類的指標或引用來訪問基類和派生類的同名函式。include using name...