C 中的多型公有繼承與虛函式

2021-08-19 21:50:15 字數 2734 閱讀 1250

繼承中的 is-a 關係

派生類和基類之間的特殊關係式基於c++繼承的底層模型的。實際上,c++有三種繼承方式:公有繼承、保護繼承、私有繼承。公有繼承是最常用的一種方式,它建立一種is-a關係,即派生類物件也是乙個基類物件,可以對基類物件執行的任何操作,也可以對派生類物件執行。用 is-a-kind-of 描述更為準確,即派生類 is-a-kind-of 基類。

多型公有繼承

有時我們會希望同乙個方法在派生類和基類中的行為是不同的,也就是方法的行為取決於呼叫該方法的物件,這叫多型。實現多型公有繼承有兩種機制:1一種是在派生類中重新定義基類的方法,另一種是使用虛方法。

class brass

};class brassplus :public brass

; void resetrate(double r) ;

void resetowes()

};

如果在派生類中重新定義基類的方法,通常應將基類方法宣告為虛方法,採用virtual關鍵字,這樣程式將根據物件型別而不是引用或指標的型別來選擇方法版本。為基類宣告乙個虛析構函式也是一種慣例。

如果上述宣告中viewacct()不是虛的,則程式將根據引用或指標的型別選擇方法版本。

brass piggy("porcelot pigg", 381299, 4000.00);

brassplus hoggy("horatio hogg", 382288, 3000.00);

brass & b1_res = piggy;

brass & b2_res = hoggy;

b1_ref.viewacct(); //use brass::viewacct()

b2_ref.viewacct(); //use brass::viewacct()

而採用virtual關鍵字,程式將根據引用或指標指向的物件型別選擇方法版本。

brass piggy("porcelot pigg", 381299, 4000.00);

brassplus hoggy("horatio hogg", 382288, 3000.00);

brass & b1_res = piggy;

brass & b2_res = hoggy;

b1_ref.viewacct(); //use brass::viewacct()

b2_ref.viewacct(); //use brassplus::viewacct()

派生類並不能直接訪問基類的私有資料,而必須使用基類的公有方法才能訪問這些資料。訪問的方式取決於方法。建構函式使用一種技術,而其他成員使用另一種技術。

派生類建構函式在初始化基類私有資料時,採用的是成員初始化列表語法。

brassplus::brassplus(const string & s, long an, double bal, double ml, double r) :brass(s, an, bal)

brassplus::brassplus(const brass & ba, double ml, double r) :brass(ba)

非建構函式不能使用成員初始化列表語法,但派生類方法可以呼叫公有的基類方法。如下

void brassplus::viewacct()const

void brassplus::withdraw(double amt)

上面幾句,由於brassplus類並沒有重新定義balance()這個函式,因此**不必對balance()使用作用域解析符。

為何需要虛析構函式?

如果析構函式不是虛的,則將只呼叫對應於指標型別的析構函式。如果析構函式是虛的,將呼叫相應物件型別的析構函式。因此,如果指標指向的是brassplus物件,將呼叫brassplus的析構函式,然後自動呼叫基類的析構函式。因此,使用虛析構函式可以確保正確的析構函式序列被呼叫。

靜態聯編與動態聯編

將源**中的函式呼叫解釋為執行特定的函式**塊被稱為函式名聯編。在c語言中這很簡單,因為每個函式名都物件乙個不同的函式。在c++中,由於函式過載,編譯器必須檢視函式引數以及函式名才能確定使用哪個函式。然而,c/c++編譯器可以在編譯過程中完成這種聯編。在編譯過程中進行聯編稱為靜態聯編、早期聯編。然而,虛函式使得在編譯時不能確定使用哪乙個函式,因為編譯器不知道使用者將選擇哪種型別的物件。所以編譯器必須生成能夠在程式執行時選擇正確的虛方法的**,這就是動態聯編,也稱為晚期聯編。

有關虛函式應注意的事項

1、建構函式不能是虛函式。因為派生類不繼承基類的建構函式,所以將類建構函式宣告為虛的沒什麼意義

2、通常應給基類提供乙個虛析構函式,即使它並不需要析構函式。

3、友元不能是虛函式,因為友元不是類成員,而只有成員才能是虛函式。

4、如果派生類沒有重新定義函式,將使用該函式的基類版本。如果派生類位於派生鏈中,則將使用最新的虛函式版本,例外的情況是基類版本是隱藏的。

5、重新定義將隱藏方法。重新定義繼承的方法並不是過載。如果重新定義派生類中的函式,無論引數列表是否相同,該操作都將隱藏所有的同名基類方法。因此,如果重新定義繼承的方法,應確保與原來的原型完全相同,但如果返回型別是基類引用或指標,則可以修改為指向派生類的引用或指標;如果基類宣告被過載了,則應在派生類中重新定義所有的基類版本。

C 多型公有繼承

標籤 空格分隔 c 版本 2本文章僅發布於 作業部落 原 csdn 如果我們希望同乙個方法在基類和派生類中的行為是不同的的時候,我們可以採取一種比較複雜的行為 多型。具有多型性質的物件的行為取決於呼叫物件,即同乙個方法的行為隨上下文而異。為了實現多型c 提供了兩種重要的機制1 無論我們是否使用多型,...

C 繼承 多型 虛函式

c 支援多繼承 class parent class parent2 class child public parent,private parent2公有繼承和私有繼承的區別 public parent 公有繼承,private和public都會繼承 private parent 私有繼承,只繼承...

C 繼承與多型之虛函式

一 定義 虛函式必須是基類的非靜態成員函式,其訪問許可權可以是private或protected或public,在基類的類定義中定義虛函式的一般形式。虛函式是一種在基類定義為virtual的函式,並在乙個或多個派生類中再定義的函式。實現多型性。虛函式的特點是,只要定義乙個基類的指標,就可以指向派生類...