繼承 加深 構造函式呼叫順序與函式重定義

2021-08-09 05:07:59 字數 2239 閱讀 7046

一、派生類的建構函式與析構函式

從基類派生子類時,基類的建構函式不能繼承到派生類中,因此我們在定義派生類的建構函式時除了對自己的資料成員進行初始化外,還必須負責呼叫基類建構函式。如果派生類中有子物件,還應包含對子物件初始化的建構函式。

派生類建構函式一般的執行順序為:

(1)最先呼叫基類的建構函式,多個基類則按派生類宣告時列出的次序,從左到右呼叫,而不是初始化列表中的次序。

(2)再呼叫物件成員(子物件)的建構函式,按類宣告中物件成員出現的次序呼叫,而不是初始化列表中的次序。

(3)最後執行派生類的建構函式。

下面我們看一段程式:

#includeusing namespace std;

class a

a(int i)

void displaya()

private:

int x1;

};class b :public a //若為多繼承,按從左到右的順序呼叫

b(int i)

:a(i + 10)

void displayb()

private:

int x2;

};int main()

執行結果為:

上述程式中,類b是類a的派生類,該成員初始化列表的順序是:先是基類a的建構函式,再是派生類b中子物件的建構函式,最後是b的建構函式。

如果類中包含物件成員呢?我們看看下面的程式:

class a

};class b

};class c

};class d :public c

};int main()

執行結果如下:

可以看出:

類c派生出類d,但類c包含乙個類a的物件a,類d中包含乙個類b的物件b,所以語句「d d」,先執行基類c中物件a的建構函式,再執行基類c的建構函式,接著是d中物件b的建構函式,最後執行類d的建構函式。

析構函式,其順序與執行建構函式時的順序正好相反。即次序如下:

(1)最先執行派生類的析構函式

(2)再呼叫物件成員(子物件)的析構函式,按類宣告中物件成員出現的逆序呼叫,

而不是初始化列表中的次序。

(3)最後呼叫基類的析構函式,多個基類則按派生類宣告時列出的逆序(從右到左)呼叫。

二、繼承成員的重定義

繼承成員的重定義是指重新修改繼承成員函式的實現。

我們先來看一段**:

class a

void disp() };

class b

void disp() };

int main()

執行結果為:

這是因為如果在派生類中增加乙個函式原型與繼承成員函式一模一樣的成員函式,則該函式實現的函式體是對繼承成員函式的重定義。

如果乙個派生類的物件呼叫這個函式,首先在派生類中查詢是否有該函式的定義,有則呼叫派生類中成員函式,否則才在所有的祖先類中查詢。

三、友元關係不能繼承

友元關係不能繼承,也就是說基類友元不能訪問子類私有和保護成員。除非在子類中也宣告為友元。

四、靜態成員資料

基類定義了static成員,則整個繼承體系裡面只有乙個這樣的成員。無論派生出多少個子類,都只有 乙個static成員例項。

我們來看乙個例子:

這就可以看出來物件共用乙個靜態成員。

繼承中的構造函式呼叫順序

呼叫派生類的建構函式之前先呼叫基類的建構函式,析構函式則相反。因為派生類需要用到基類的成員,所以必須先有基類,再有派生類。c 語法規定 如果類沒有顯示定義建構函式,則編譯器提供乙個預設建構函式 不帶引數,僅建立物件,不初始化 如果類顯示定義了建構函式,編譯器一律不提供預設建構函式。即如果乙個類定義了...

java繼承的構造函式呼叫順序

1 首先呼叫父類的無參建構函式 這個建構函式必定會被呼叫 2 呼叫子類的無參建構函式或帶引數的建構函式 例 1 宣告抽象類爺爺 father of abstractclass public abstract class father of abstractclass protected father...

繼承和建構函式析構函式呼叫順序

繼承 的重用性 using namespace std 人類 class human protected char name int age 男人 class man public human private 兄弟 char brother void work human h void main 向...