C 繼承多型筆試面試題實戰分析

2021-10-24 15:09:21 字數 3954 閱讀 5875

目錄

例題一 

例題二 

例題三 

例題四例題五

#include#includeusing namespace std;

class animal

virtual void bark() = 0;

protected:

string _name;

};class cat :public animal

void bark() };

class dog :public animal

void bark() };

int main()

執行結果:

例題分析:

兩個基類指標p1p2分別指向了兩個派生類物件catdog,接著將兩個基類指標p1p2強轉為int*型別。我們知道,抽象類構造出來的的物件的前4個位元組為虛函式指標vfptr的記憶體空間。而在上述**中,我們將p1p2vfptr進行了調換,因此當p1p2分別呼叫虛函式bark()時,發生了動多型,系統會根據vfptr所指向的vftable去尋找虛函式bark()的位址,因為此時p1p2中的vfptr已經互換,所以p1會呼叫dog類中的虛函式bark(),而p2則會呼叫cat類中的虛函式bark()

#includeusing namespace std;

class base

};class derive : public base

};int main()

執行結果:

例題分析:

首先我們讓基類指標p指向了派生類物件,接著使用指標p呼叫了虛函式show(),發生了動多型,但我們發現列印出來的i的值卻是基類中show()函式i的值,這是因為形參入棧是發生在編譯時期的,而動多型是在執行時期發生的。當在編譯時期,**執行到

p->show();
這一步時,因為pbase型別的指標,因此,此時發生的是靜態的繫結,系統認為p呼叫的是base類中的show()函式,因此此時引數i入棧,且此時i的值為10,而當執行階段,**再次執行到

p->show();
這一步時,因為show是虛函式,因此發生了動多型,呼叫derive類中的show()函式,但此時列印的i的值是之前在編譯間段就已經入棧的i,即最終列印的i的值為10。

#includeusing namespace std;

class base

};class derive : public base

};int main()

執行結果:

例題分析:

首先,我們用乙個基類指標p指向了乙個派生類物件,接著用這個指標p呼叫了虛函式show(),在編譯間段,當**執行到

p->show();
這一行時, 因為p是base型別的指標,此時發生的是靜態的繫結,系統認為p呼叫的是base類中的show()函式,且我們注意到base類中的show()函式的訪問限定符是public,即可以在類外呼叫。

而當執行階段,**再次執行到

p->show();
這一步時,因為show是虛函式,因此發生了動多型,呼叫derive類中的show()函式,我們知道呼叫虛函式的過程是p在vfptr所指向的vftable中尋找虛函式show()的位址,找到這個位址後,直接呼叫該函式,此時已與show()的函式訪問限定符無關,所以,雖然派生類中的show()是私有的,但最終發生動多型時,我們依然可以呼叫它。

#includeusing namespace std;

class base

void clear()

virtual void show() };

class derive : public base

void show() };

int main()

執行結果:

例題分析:

我們發現最終的執行結果顯示程式執行錯誤。原因是,我們用乙個基類指標指向了乙個基類物件,在構造這個基類物件的時候會呼叫它的建構函式,而在它的建構函式中我們又呼叫了clear()函式,將這個基類物件所佔記憶體空間的值全部賦為0,即此時vfpter的值也變為了0,所以雖然在程式執行間段發生了動多型,但因為vfptr的值為0,系統無法根據vfptr找到虛函式show()的入口位址,那麼也就無法呼叫虛函式show()。

#includeusing namespace std;

class base

void clear()

virtual void show() };

class derive : public base

void show() };

int main()

執行結果:

例題分析:

我們定義了乙個基類指標指向了乙個派生類物件,在構造這個派生類物件的時候會先構造基類部分,因此就會呼叫基類的建構函式,而基類的建構函式中又呼叫了clear()函式,將派生類物件中基類部分所佔的記憶體空間的值賦為0,即此時vfptr的值為0,構造完基類部分後,就會構造派生類自己的那部分,此時就會將vfptr指向派生類自己的vftable,因此在程式執行間段,當p2呼叫虛函式show()的時候就會發生動多型,即p2最終會在vfptr所指向的vftable中尋找派生類中show()函式的入口位址,接著呼叫它。 

C 多型繼承相關面試題

一 相關概念 類的編譯順序 類名 成員名 成員方法體 類的構造順序 成員物件 類物件 子類的構造 父類 子類 子類的析構 子類 父類 過載 函式名相同 引數列表不同 作用域相同 隱藏 子類隱藏父類中同名的成員方法 覆蓋 子類覆蓋父類中相同的許成員方法 動多型 繼承中的多型 執行時期決定的多型 靜多型...

C 多型面試題

答 多型是物件導向的重要特性之一,它是一種行為的封裝,是同一種事物所表現出的多種形態,簡單地說是 乙個介面多種實現 有兩種型別的多型性 編譯時的多型性。編譯時的多型性是通過過載來實現的。執行時的多型性。執行時的多型性是通過虛成員實現的。1.從儲存空間角度。虛函式對應乙個vtable,這個vtable...

C 面試題之繼承 過載 多型

1.什麼是繼承?繼承的作用是什麼?2.什麼是過載 什麼是覆蓋 重寫 什麼是隱藏 重定義 相同的作用域 在同乙個類中 函式名相同引數不同virtual 關鍵字可有可無 不同的作用域 分別位於派生類與基類 函式名相同 引數相同 基類中必須有 virtual 關鍵字 注意 重寫基類函式的時候,會自動轉換這...