繼承與多型中常見的問題(二)

2021-08-07 02:12:56 字數 2065 閱讀 3371

繼承與多型中常見的問題分析

1、畫出派生類derive的記憶體布局

(1)如果base中的show函式是虛函式,那麼p->show();則動態繫結,列印出derive::show();

(2)如果base中的show函式不是虛函式,derive中的show函式不是虛函式,那麼p->show(),則靜態繫結,列印出base::show();

(3)如果base中的show函式不是虛函式,derive中的show函式是虛函式,那麼p->show(),則在編譯器發現base::show()不是虛函式,則不會發生動態繫結,故列印base::show();此時的記憶體布局是:

但是在執行上述main()**中,執行到delete p時會崩潰。原因是:基類指標指向派生類物件,指標永遠指向基類部分的起始位址,但是此時派生類的起始位址和基類的起始位址不在一起,故從基類起始位址處釋放則會崩潰。(開闢和釋放的記憶體不在一起)

注:delete呼叫的析構函式是指標型別 。new和delete兩者配對使用,兩者不配對使用的情況有:(1)自定義型別 (2)提供了自定義型別的析構函式

2、為什麼要將基類的析構函式寫為虛函式?

由以上可知:當基類物件指標指向堆上的派生類物件時,需要將基類 的析構函式寫為虛析構函式。

3、

#includeusing namespace std;

class base

; base( int data ) ;//執行clear()前的彙編指令為:

/*
push ebp
mov ebp,esp
sub esp,4ch
rep ……
vftable->vfptr
*/

void clear()

virtual void show()

此時程式崩潰的原因是:在呼叫建構函式base時,呼叫了clear()將記憶體中的元素清空為0,(也將前4個位元組(存放vfptr)置為0)

(2)

int main()

(3)去掉base建構函式中的clear(),給base和derive建構函式中加上show(),並不會發生動態繫結,因為在建構函式中物件還沒有生成,不會發生多型。

(4)在base的析構函式中呼叫show();,此時不會發生動態繫結,因為析構完後物件已經不存在了,所以不會發生。

(5)將派生類中的成員函式設為私有的,在編譯時期,是否會發生編譯錯誤?(訪問限定符只可以在編譯階段起作用)

由此可見:將派生類的虛函式設為私有的,編譯不會出錯,此時這個函式能否被呼叫主要取決於基類中該虛函式的訪問限定符。 4、

注:成員能不能被訪問,訪問許可權是否正確?函式的預設值用哪個?這些均是在編譯時期都已經確定好了,最終呼叫哪個派生類物件的方法在執行時確定。(在虛表中取誰的位址,執行時就呼叫誰)。

繼承和多型中常見的問題(一)

繼承和多型中常見的問題 一 一 繼承 的復用。繼承允許我們依據另乙個類來定義乙個類,這使得建立和維護乙個應用程式變得更容易。這樣做,也達到了重用 功能和提高執行時間的效果。1 繼承的方式 由於c 中有三種訪問限定符,public,private,protected.因此在類與類的繼承中也將有這三種方...

C 繼承與多型(二)

多型 虛函式 類成員函式前面加virtual關鍵字 虛函式重寫 當在子類的定義了乙個與父類完全相同的虛函式時,則稱子類的這個函式重寫了這個父類的這個虛函式 滿足條件 1.虛函式的重寫 2.父類的指標 引用呼叫虛函式 多型跟型別無關,與物件有關 多型 當使用基類的指標或引用調重寫的虛函式時,當指向父類...

c (八) 繼承與多型(二)

一 抽象類與動態型別轉換 1 訪問控制屬性 類的定義中有public private和protected三個關鍵字,其中private關鍵字說明類中成員為私有成員,只能在類內的函式訪問 public成員為公有成員,可被任何其他類訪問,protected關鍵字是保護屬性,保護屬性的資料或函式可被派生類...