C 之多型和虛函式

2021-07-24 14:15:34 字數 4233 閱讀 9080

一.什麼是多型

多型與封裝,繼承一起構成了物件導向的3大特性。多型指向不同物件傳送同一訊息,不同的物件會產生不同的行為。也就是說每個物件用自己的方式去響應共同的訊息。

c++有倆中形式的多型。如上課鈴打了,不同班級的同學走向不同的教室。

編譯時的多型性,即靜態聯編:

程式在編譯之前就可以確定的多型性,通過過載機制來實現的,可以是函式過載,也可以是運算子過載。

執行時多型性,即動態聯編:

必須在執行時才可以確定的多型性,通過繼承和虛函式來實現。使用virtual關鍵字修飾類的成員函式時,指明該函式為虛函式,派生類需要重新實現,編譯器將實現動態繫結。

如:virtual double area()

二..虛函式的定義

為了實現某種功能而假設的函式稱為虛函式。

const

double ip = 3.14159;

class cpint

public:

cpint(double x,double y)

this->x = x;

this->y = y;

virtual

double area()

return 0;

private:

double x,y;

class ccircle : public cpint

public:

ccircle(double x,double y,double radius) : cpint(x,y)

this->radius = radius;

double area()

return ip * radius * radius;

private:

double radius;

void main()

cpint pint(4.0,4.0);

ccircle circle(5.0,6.0,10);

cout <

cout<

cout<

cout<

但是如果要讓程式實現下面這種結果:

就是要cpint的指標指向

ptr_ccircle

的成員函式

area

virtual,

將這種函式稱為虛函式:

virtual double area()

如果派生類沒有改寫繼承類的虛函式,則函式指標呼叫基類的虛函式。如果派生類改寫了基類的虛函式,編譯器將重新為派生類的虛函式建立位址,函式指標呼叫改寫過的虛函式。

總結:如果派生類中有與基類同名的成員函式,並且基類指標指向派生類的物件,那麼基類指標呼叫的函式是派生類的函式

三..動態聯編的工作機制。

當編譯器編譯遇到virtual關鍵字的時候,將自動為包含

virtual

的函式建立一張虛函式表,在這個虛函式表中依次存放了特定虛函式的位址。同時在每個帶有虛函式的類中放置乙個指標。如果基類的成員函式定義為虛函式,那麼他所在的派生類中也保持為虛函式,(

virtual

在派生類中可以省略)

對於虛函式有以下幾點說明:

1.基類成員函式定義為虛函式後,要使達到動態聯編的效果,派生類和基類對應的函式名,返回值型別,引數個數和型別也必須相同。

2.基類中虛函式的virtual關鍵字不能省略,派生類中虛函式的關鍵字可以省略。

3.執行時虛函式必須通過基類物件的引用或基類物件的指標呼叫虛函式才能實現。

4.虛函式必須是類的成員函式,不能是友元函式也不能是靜態成員函式。

5.不能將建構函式定義成虛函式(建構函式執行時,物件還沒有完全構造好),但可以將析構函式定義成虛函式。

四.虛析構函式

如果基類析構函式為虛析構函式,則釋放基類指標的時候會呼叫基類和派生類中所有的析構函式,派生類物件的所有記憶體空間都將被釋放。因此c++中析構函式通常為虛析構函式。

定義方法為:

vietual  ~ 類名();

五.純虛函式與抽象類

純虛函式是在宣告虛函式時被「初始化」為0

的函式,純虛函式只有函式的名字而不具備函式的功能,不能被呼叫。至少含有乙個純虛函式的類稱為抽象類

純虛函式:它的作用是在基類中為其派生類保留乙個函式的名字,以便派生類根據需要對它進行定義。如果在基類中,沒有保留函式的名字,無法實現多型。純虛函式的一般形式為:

class 類名

virtual 型別 函式名(參數列)

= 0;

//純虛函式

注意:1.純虛函式沒有函式體

2.「=0」只是形式上的作用,告訴編譯器此為純虛函式。

抽象類:class 類名

public :

virtual 返回值型別 函式名(參數列)

= 0;

其他函式的而宣告;

注意:1.抽象類只能用作其他類的基類,抽象類不能建立物件

2.抽象類不能用作函式引數型別、函式返回型別或顯示轉換型別。

3.可以宣告抽象類的指標和引用。

抽象類例項:

class cperson   //抽象型別

public:

virtual

void printinfo()  //基類中的虛構函式

cout <

\n";

virtual

void displaysalary(int m,double s) = 0;//抽象類中的純虛函式

class cworker :public cperson

public:

void printinfo()   //在派生類中重新定義

cout <

\n";

void displaysalary(int m,double s)

cout <

"int kindofwork;

class cteacher:public cperson

public:

void printinfo()

cout << "教師

\n";

void displaysalary(int m,double s)

cout <

"int subject;

class cdriver:public cperson

public:

void printinfo()

cout <

\n";

void displaysalary(int m,double s)

cout <

"int subject;

void main()

cworker worker;   //分別對三個類的物件進行宣告

cteacher teacher;

cdriver driver;

cperson *person;   //指向父類的指標變數

person

person = &worker;   //指向派生類,獲取的是指向派生類的虛表指標

person -> printinfo();

person -> displaysalary(12,1800.35);

person = &teacher;

person -> printinfo();

person -> displaysalary(12,1300.45);

person = &driver;

person -> printinfo();

person -> displaysalary(12,1700.78);

system("pause");

執行結果為:

在這個程式中cperson類中的虛函式

displaysalary(int m,double s)

僅起到為派生類提供乙個介面的作用,而派生類中重新定義的

displaysalary(int m, double s)

用於取決什麼樣的方式來計算工資。由於在

cperson

中不能對此作出決定,因此被說明為純虛函式。

工人,教師和司機

等都視為人類的物件,多型性保證了函式在對不同人群計算工資時,無需關心當前正在計算那類人。在需要時函式可以從這些不同人群的子類中獲得該物件的工資。

c 之多型和虛函式(二)

一 虛函式的過載特性 1 在派生類中過載基類的虛函式要求函式名 返回型別 引數個數 引數型別和順序完全相同 2 如果僅僅返回型別不同,c 認為是錯誤過載 3 如果函式原型不同,僅函式名相同,丟失虛特性 4 舉例 class derived public base void g 二 虛析構函式 1 建...

C 之多型性與虛函式

物件導向程式設計中的多型性是指向不同的物件傳送同乙個訊息,不同物件對應同一訊息產生不同行為。在程式中訊息就是呼叫函式,不同的行為就是指不同的實現方法,即執行不同的函式體。也可以這樣說就是實現了 乙個介面,多種方法 從實現的角度來講,多型可以分為兩類 編譯時的多型性和執行時的多型性。前者是通過靜態聯編...

C 之多型性與虛函式

物件導向程式設計中的多型性是指向不同的物件傳送同乙個訊息,不同物件對應同一訊息產生不同行為。在程式中訊息就是呼叫函式,不同的行為就是指不同的實現方法,即執行不同的函式體。也可以這樣說就是實現了 乙個介面,多種方法 從實現的角度來講,多型可以分為兩類 編譯時的多型性和執行時的多型性。前者是通過靜態聯編...