複習六 虛函式與多型性

2021-10-07 11:45:41 字數 4153 閱讀 8553

一、靜態聯編

(1)聯編是指乙個程式模組、**之間互相關聯的過程。

靜態聯編,是程式的匹配、連線在編譯階段實現,也稱為早期匹配。過載函式使用靜態聯編。

動態聯編是指程式聯編推遲到執行時進行,所以又稱為晚期聯編。switch 語句和 if 語句是動態聯編的例子。

(2)過載函式要根據型別、引數進行匹配,一般在編譯階段進行靜態聯編

普通成員函式過載可表達為兩種形式::

a.在乙個類說明中過載

例如:  

void show ( int , char ) ;

void show ( char * , float ) ;

b.基類的成員函式在派生類過載。有 3 種編譯區分方法:

(a1)根據引數的特徵加以區分

例如:    void show ( int , char );       與

void show ( char * , float ); 不是同一函式,編譯能夠區分

(a2)使用「 :: 」加以區分

例如:        a :: show ( );

有別於    b :: show ( );

(a3)根據類物件加以區分

例如:    aobj . show ( )    呼叫    a :: show ( )

bobj . show ( )    呼叫    b :: show ( )

二、類指標的關係

基類指標和派生類指標與基類物件和派生類物件4種可能匹配:

直接用基類指標引用基類物件;

直接用派生類指標引用派生類物件;

用基類指標引用乙個派生類物件;

用派生類指標引用乙個基類物件。 例如:

class a

;class b:public a

;a    * p ;        // 指向型別 a 的物件的指標

a    a_obj ;    // 型別 a 的物件

b    b_obj ;    // 型別 b 的物件

p = & a_obj ;    // p 指向型別 a  的物件

p = & b_obj ;    // p 指向型別 b  的物件,它是 a 的派生類

利用 p,可以通過 b_obj 訪問所有從 a 類繼承的元素 ,但不能用 p訪問 b 類自定義的元素 (除非用了顯式型別轉換)

例題一:使用基類指標引用派生類物件

#include#includeusing namespace std;

class a_class

void show_name()

派生類指標只有經過強制型別轉換之後,才能引用基類物件 

例題二:日期時間程式。在派生類中呼叫基類同名成員函式

#include#includeusing namespace std;

class date

void setdate(int y,int m,int d)

void print()

void who()

輸出結果:

a

t et oe n d

(2)、虛函式和基類指標注意:

乙個虛函式,在派生類層面相同的過載函式都保持虛特性

虛函式必須是類的成員函式

不能將友元說明為虛函式,但虛函式可以是另乙個類的友元

析構函式可以是虛函式,但建構函式不能是虛函式

在派生類中過載基類的虛函式要求函式名、返回型別、引數個數、引數型別和順序完全相同

如果僅僅返回型別不同,c++認為是錯誤過載

如果函式原型不同,僅函式名相同,丟失虛特性

例題四虛函式過載特性

#includeusing namespace std;

class  base

;class  derived : public  base

;void  g ( ) 

;

(3)、虛析構函式(建構函式不能是虛函式,析構函式可以是虛的,虛析構函式用於指引delete運算子正確析構動態物件)例題五a,普通析構函式在刪除動態派生類物件的呼叫情況

#includeusing namespace std;

class  a

};class  b:public a

};int main()

輸出結果:

delete first object

a::~a() is called.

delete second object

b::~b() is called.

a::~a() is called.例題五b

#includeusing namespace std;

class  a

};class  b:public a

};int main()

輸出結果:

delete first object

b::~b() is called.

a::~a() is called.

delete second object

b::~b() is called.

a::~a() is called.

四、純虛函式和抽象類

純虛函式說明形式:

virtual  型別  函式名(參數列)= 0 ;

乙個具有純虛函式的基類稱為抽象類。 

純虛函式為各派生類提供乙個公共介面

class  point  ;

class  shape ;         // 抽象類

void  move ( point p )

virtual  void  rotate ( int ) = 0 ;         // 純虛函式

virtual  void  draw ( ) = 0 ;            // 純虛函式

} ;      …...

hape  x ;            // error,抽象類不能建立物件

shape  *p ;        // ok,可以宣告抽象類的指標

shape  f ( ) ;        // error, 抽象類不能作為函式返回型別

void  g ( shape ) ;        // error, 抽象類不能作為傳值引數型別

shape  & h ( shape &) ;    // ok,可以宣告抽象類的引用

五、虛函式與多型的應用

例題六計算雇員工資

#include#include#include#includeusing namespace std;

class employee

;employee::employee(const long k,const char*str)

employee::~employee()

const char*employee::getname() const

const long employee::getnumber() const

void employee::print()const

double manager::earnings() const

void manager::print()const

void hourlyworker::sethours(int h)

double hourlyworker::earings()const

void hourlyworker::print()const

void pieceworker::setquantity(int q)

double pieceworker::earnings()const

void pieceworker::print()const

六、異質鍊錶

把不同類物件統一組織在乙個資料結構中,可以定義抽象類指標陣列或鍊錶。

由於這種表中具有不同類型別元素(它們都有共同的基類),所以稱為「異質表」。 

例題(接上)

void test2()

實驗六 多型性與虛函式

了解靜態聯編的動態聯編的概念。1.分析並除錯下列程式。include using namespace std class base 1 找出以上程式中使用了過載和覆蓋函式。答 base類中函式void g 和void h 與derived類中的函式void g 和void h 函式名相同,引數型別不...

實驗六 多型性與虛函式

一 實驗目的和要求 了解靜態聯編和動態聯編的概念。掌握動態聯編的條件。二 實驗內容 1 分析並除錯下列程式。cpp view plain copy sy6 1.cpp include using namespace std class base class derived public base i...

虛函式與多型性

實驗內容 定義基類base,其資料成員為高h,定義成員函式disp 為虛函式,由基類派生出長方體類和圓柱類,並在兩個派生類中定義成員函式disp 為虛函式。在主函式中,用基類base定義指標p,用指標p動態呼叫虛函式disp 顯示面積。虛函式 它是基類中的成員函式,並在派生類中被過載。派生類中的虛函...