C 多重繼承及多型性原理例項詳解

2022-09-29 16:09:14 字數 4453 閱讀 5093

一、多重繼承的二義性問題

舉例:#include

using namespace std;

class basea

};class baseb

void tun()

};class derived :public basea, public baseb

void hun() //此處呼叫出現二義性,編譯無法通過

};int main()

類名限定

void hun() //改寫上述**的第14行,用basea類名限定呼叫的函式

d.baseb::fun(); //派生類物件呼叫基類同名函式時,使用類名限定

p->baseb::fun(); //派生類指標呼叫基類同名函式時,使用類名限定

名字支配規則

如果存在兩個或多個包含關係的作用域,外層宣告了乙個名字,而內層沒有再次宣告相同的名字,則外層名字在內層可見;如果在內層宣告了相同的名字,則外層名字在內層不可見——隱藏(遮蔽)規則。

在類的派生層次結構中,基類的成員和派生類新增的成員都具有類作用域,二者的作用域不同:基類在外層,派生類在內層。如果派生類宣告了乙個和基類成員同名的新成員,則派生類的新成員就會遮蔽基類的同名成員,直接使用成員名只能訪問到派生類新增的成員。(如需使用從基類繼承的成員,應當使用基類名限定)

#include

using namespace std;

class base

base(int x = 1, int y = 2) :x(x), y(y) {}

int x, y;

};class derived :public base

void fun()

derived(int x = 0) :x(x) {}

int x;

};int main()

二、虛基類

虛基類的使用目的:在繼承間接基類時只保留乙份成員。

宣告虛基類需要在派生類定義時,指定繼承方式的時候宣告,只需要在訪問標號(public、protected、private繼承方式)前加上virtual關鍵字。注意:為了保證虛基類在派生類中只繼承依次,應當在該基類的所有直接派生類中宣告為虛基類,否則仍會出現多次繼承。

派生類不僅要負責對直接基類進行初始化,還要負責對虛基類初始化;若多重繼承中沒有虛基類,則派生類只需要對間接基類進行初始化,而對基類的初始化由各個間接基類完成(會因此產生多個基類的副本儲存在各個間接基類中)。

#include

using namespace std;

class base

void fun()

private:

int nv;

};class a:virtual public base

private:

int na;

};class b :virtual public base

private:

int nb;

};class derived :public a, public b

程式設計客棧 //派生類的建構函式初始化列表,先呼叫基類base的建構函式,再依次呼叫間接基類a、b的建構函式

//由於虛基類base中沒有預設建構函式(允許無參構造),所以從base類繼承的所有派生類的建構函式初始化表中都需要顯式呼叫基類(包括間接基類)的建構函式,完成初始化

private:

int nd;

};int main()

關於虛基類的說明:

乙個類在乙個類族中既可以被用作虛基類,也可以被用作非虛基類;

如果虛基類中沒有預設建構函式(或引數全部為預設引數的),則在派生類中必須顯式宣告建構函式,並在初始化列表中列出對虛基類建構函式的呼叫;

在乙個成員初始化列表中同時出現對虛基類和非虛基類建構函式的呼叫時,虛基類的建構函式先於非虛基類的建構函式執行。

三、虛函式

虛函式概念:被virtual關鍵字修飾的成員函式,即為虛函式,其作用就是實現多型性。

虛函式使用說明:

虛函式只能是類中的成員函式,且不能是靜態的;

virtual關鍵字只能在類體中使用,即便虛函式的實現在類體外定義,也不能帶上virtual關鍵字;

當在派生類中定義了乙個與基類虛函式同名的成員函式時,只要該函式的引數個數、型別、順序以及返回型別與基類中的完全一致,則派生類的這個成員函式無論是否使用virtual關鍵字,它都將自動成為虛函式;

利用虛函式,可以在基類和派生類中使用相同的函式名定義函式的不同實現,達到「乙個介面,多種方式」的目的。當基類指標或引用對虛函式進行訪問時,系統將根據執行時指標(或引用)所指向(或引用)的實際物件來確定呼叫的虛函式版本;

使用虛函式並不一定產生多型性,也不一定使用動態聯編。如:在呼叫中對虛函式使用類名限定,可以強制c++對該函式使用靜態聯編。

在派生類中,當乙個指向基類成員函式的指標指向乙個虛函式,並且通過指向物件的基類指標(或引用)訪問這個虛函式時,仍將發生多型性。

#include

using namespace std;

class base

};class derived :public base

};void display(base* p, void(base::* pf)())

int main()

使用虛函式,系統要增加一定的空間開銷儲存虛函式表,但是系統在進行動態聯編時的時間開銷時很少的,因此,虛函式實現的多型性是高效的。

虛函式實現多型的條件(同時滿足)

類之間的繼承關係滿足賦值相容規則;

改寫了同名的虛函式,但函式形參、返回型別要保持一致;

根據賦值相容規則使用指標(或引用);

虛析構函式

派生類的物件從記憶體中撤銷時一般先呼叫派生類的析構函式,然後再呼叫基類的析構函式。但如果用new運算子建立了派生類物件,且定義了乙個基類的指標指向這個物件,那麼當用delete運算子撤銷物件時,系統會只執行基類的析構函式,而不執行派生類的析構函式,因而也無法對派生類物件進行真正的撤銷清理工作。

如果希望delete關鍵字作用於基類指標時,也執行派生類的析構函式,則需要將基類的析構函式宣告為虛函式。

如果將基類的析構函式宣告為虛函式,則由該基類所派生的所有派生類的析構函式也都自動成為虛函式,即使派生類的析構函式與基類的析構函式名字不相同。

c++支援虛析構函式,但是不支援虛建構函式,即建構函式不能宣告為虛函式!

純虛函式

許多情況下,不能在基類中為虛函式給出乙個有意義的定義,這時可以將它說明為純虛函式,將具體定義留給派生類去做。純虛函式的定義形式為:virtual 返回型別 函式名(形式引數列表) = 0;

包含有純虛函式的類稱為抽象類,乙個抽象類只能作為基類來派生新類,因此又稱為抽象基類,抽象類不能定義物件(實體)。

四、多型性

多型的含義:指同一操作作用於不同的物件時產生不同的結果程式設計客棧。

至少含有乙個虛函式的類稱為多型類,虛函式使得程式能夠以動態聯編的方式達到執行結果的多型化。這種多型使用的背景是:派生類繼承基類的所有操作,或者說,基類的操作能被用於操作派生類的物件,當基類的操作不能適應派生類時,派生類就需要過載基類的操作;其表現為c++允許用基類的指標接收派生類的位址或使用基類的引用繫結派生類的物件。

靜態聯編和動態聯編

聯編:將模組或者函式合併在一起生成可執行**的處理過程,同時對每個模組或者函式分配記憶體位址,並且對外部訪問也分配正確的記憶體位址。

靜態聯編:在編譯階段就將函式實現和函式呼叫繫結。靜態聯編在編譯階段就必須了解所有函式的或模組執行所需要的資訊,它對函式的選擇是基於指向物件的指標(或者引用)的型別。c語言中,所有的聯編都是靜態聯編,c++中一般情況下的聯編也是靜態聯編。

動態聯編:在程式執行的時候才進行函式實現和函式呼叫的繫結稱之為動態聯編(dynamic binding)

#include

#define pi 3.14159265

using namespace std;

class point

double area_static() //不是虛函式,只會在編譯期繫結,形成靜態聯編

virtual double area_dynamic() //用虛函式宣告,則編譯時只做賦值相容的合法性檢查,而不做繫結

private:

double x, y;

};class circle :public point //由於基類中的建構函式非必須顯式傳參,所以系統會自動呼叫基類帶預設引數的建構函式

circle(double x, double y, double r=1.0) :point(x, y), r(r) {} //過載乙個可傳座標點、半徑值引數的建構函式

double area_static() //靜態聯編

double area_dynamic() //動態聯編(仍為虛函式),為使可讀性更好,可在不預設virutal關鍵字

private:

double r;

};int main()

動態聯編與虛函式

本文標題: c++多重繼承及多型性原理例項詳解

本文位址:

c 繼承 多重繼承 多型性 虛函式

從繼承的角度來看,y 所繼承到的成員 x 的資料成員 的訪問屬性 x作為y 的成員,屬性是由繼承方式決定的,訪問屬性可由普通成員屬性推理理解 多重繼承的訪問屬性 可按照 上邊 繼承加遞迴的思想理解 多型性virtual this 編譯器幫助我們簡化操作,通過虛函式 方便多多 總結c 讓編譯器多做點工...

C 多型性原理

靜態多型性比較簡單,主要動態多型性比較難理解。動態多型性有兩個條件 1 在基類中必須使用虛函式 純虛函式 2 呼叫函式時要使用基類的指標或引用。只要在基類的成員函式前加上virtual,該成員函式就是虛函式,從基類派生出來的類的同名成員函式,不管前面是否有virtual,同樣是虛函式,在虛函式的實現...

C 繼承與多型性

編寫乙個人員資訊管理系統。這個系統的功能是 互動式的實現校園人員資訊的錄入與顯示。分析 學校裡,主要有四類人員 大學本科學生 教師 研究生和助教。大學本科生每週有固定的學時數。教師除了固定的學時數外,還有每週的教學時數。研究生除了固定的學時數外,每週還可以自由做一定的研究。助教生除了上課外,還要做研...