虛函式和多型

2021-08-19 08:43:46 字數 2942 閱讀 8470

知識儲備:

重提切片行為:

1.子類物件賦值給父類物件

2.父型別的指標指向了子類物件

3.父型別的引用引用子類的物件

虛函式:類的成員函式前面加virtual關鍵字,則這個成員函式稱為虛函式

虛函式重寫:當在子類的定義了乙個與父類完全相同的虛函式時,則稱子類的這個函式重寫(也稱覆蓋)了父類的這個虛函式

構成多型需要滿足的條件:

1.函式的形參是父類的指標或者引用

2.呼叫的func必須是虛函式的重寫

構成多型的函式的呼叫只與呼叫函式函式的物件有關,(父類物件還是子類物件)

常規的函式呼叫只與型別有關,(父類還是子類)

小記:

1>虛函式使用基類指標或者引用呼叫時會發生動態繫結,

2>動態繫結又稱晚繫結(執行時繫結),函式執行時的版本由實參決定,即在執行時選擇函式版本。

3>類成員函式沒有宣告為虛函式,則其解析過程發生在編譯而非執行時。

class person

protected:

string _name; // 姓名

};class student : public person

protected:

int _num; //學號

};//void fun(peron p) //不構成多型,與型別有關,這裡都呼叫的是基類的函式

//void fun(person* p) //構成多型

void fun(person& p) //構成多型

// 不夠多型的常規呼叫 -- 跟型別有關

// 構成多型 -- 跟物件有關

//構成多型的行為

// 1.父類指標和引用

// 2.呼叫的func必須是虛函式的重寫

void test()

總結:1. 派生類重寫基類的虛函式實現多型,要求函式名、引數列表、返回值完全相同。(協變除外)2. 基類中定義了虛函式,在派生類中該函式始終保持虛函式的特性3. 只有類的非靜態成員函式才能定義為虛函式, 靜態成員函式不能定義為虛函式4. 如果在類外定義虛函式,只能在宣告函式時加virtual,類外定義函式時不能加virtual。

5. 建構函式不能為虛函式,雖然可以將operator=定義為虛函式,但是最好不要將operator=定義為虛函式,因為容易使用時容易引起混淆。

6. 不要在建構函式和析構函式裡面呼叫虛函式,在建構函式和析構函式中,物件是不完整的,可能會發生未定義的行為。

7.最好把基類的析構函式宣告為虛函式。(why?析構函式比較特殊,因為派生類的析構函式跟基類的析構函式名稱不一樣,但是構成覆蓋,這裡是因為編譯器做了特殊處理)

8.虛表是所有類物件例項共用的

class a                              //把基類的析構函式最好宣告為虛函式

};class b :public a

};int main()

純虛函式:在成員函式的形參後面寫上=0,則成員函式為純虛函式。包含純虛函式的類叫做抽象類(也叫介面類),抽象類不能例項化出物件。純虛函式在派生類中重新定義以後,派生類才能例項化出物件。

class person

;class teacher : public person

protected:

string _name;

};class student : public person

protected:

string _name;

};int main()

解惑:1.什麼是協變?函式的返回值型別可以不同,但返回值型別必須是本類的指標或者引用。2.建構函式為什麼不能宣告稱虛函式?1>構造乙個物件的時候,必須知道物件的實際型別,而

虛函式行為是在執行期間確定實際型別的

。而在構造乙個物件時,由於物件還未構造成功。編譯器無法知道物件 的實際型別,是該類本身,還是該類的乙個派生類,或是更深層次的派生類。

2>虛函式的執行依賴於虛函式表。而

虛函式表在建構函式的初始化列表中進行初始化工作

,即初始化vptr,讓它指向正確的虛函式表。而在構造物件期間,虛函式表還沒有被初始化,將無法進行。

多型原理:

將父類的函式宣告成虛函式,子類繼承時就會生成自己虛表,即父子類具有各自不同的虛表。

當指標(或引用)指向父類時,就在父類的虛表中查詢指定的函式,當指標執行子類時,便在子類的虛表中查詢。

多型和虛函式

在c 中,多型是通過虛函式實現的。基類如果把乙個函式宣告為虛的 virtual 就表明繼承類可以覆蓋 override 這個函式 從而表現不同的行為,呈現出多型性 對於每乙個有虛函式的類,或者覆蓋了乙個或多個基類虛函式的繼承類,可認為有乙個與之關聯的虛函式表 v table v table 表中的每...

虛函式和多型

虛函式的概念 在類的成員函式前加virtual關鍵字,這個成員函式稱為虛函式。虛函式重寫 當在子類的定義了乙個與父類完全相同的虛函式時,則稱子類的這個函式重寫 也稱覆蓋 了父類的這個虛函式。include using namespace std class person public virtual...

虛函式和多型

pragma once 普通飛機 class plane include plane.h include using namespace std void plane fly void plane land pragma once include plane.h 直公升飛機 class jet pu...