一、靜態聯編
(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 顯示面積。虛函式 它是基類中的成員函式,並在派生類中被過載。派生類中的虛函...