1. 程式人生 > >c++基礎知識點(四)

c++基礎知識點(四)

第四章

多型

靜態多型性:編譯階段繫結(早期聯編),通過函式過載實現

動態多型性:執行時動態繫結(之後聯編),通過虛擬函式和繼承實現

動態繫結的條件:

  1. 在虛基類中定義虛擬函式
  2. 使用指向基類的指標或引用呼叫虛擬函式

虛擬函式必須是成員函式,且必須是非靜態成員函式。(靜態成員函式都是早期聯編的)。

當基類中某個成員函式定義為虛擬函式時,在派生類中就要重新定義該函式,且函式簽名必須完全一致。

虛擬函式不能是行內函數

建構函式不能是虛擬函式

解構函式可以是虛擬函式

虛擬函式的覆蓋

出原型完全相同的虛擬函式在基類、派生類中形成覆蓋關係外,其他同名函式形成隱藏關係。隱藏和覆蓋都讓派生類物件無法訪問基類同名函式。但當通過基類指標或引用訪問派生類中的隱藏或覆蓋函式時會有不同結果。覆蓋函式會呼叫派生類中的新定義的函式,隱藏函式會呼叫基類中的函式而不能呼叫派生類中的新定義的函式。

虛擬函式的傳遞性

虛擬函式具有傳遞性,即在多重繼承中基類派生的所有派生類的原型相同的函式都是虛擬函式,具有虛擬函式的一切特性。通過基類的指標或引用可以呼叫該基類派生的所有派生類的所有原型相同的函式,且都具有多型性。

在有繼承關係時,解構函式應設計為虛擬函式。

建構函式儘量採用初始化列表的方式初始化派生類的建構函式,以提高效率。因為初始化列表會在函式體內的賦值語句執行前執行,且效率比函式體內的賦值語句高。

抽象類

Class 類名

{

Public:

    Virtual 函式返回型別 函式名(引數表)=0;

}

虛擬函式必須有函式實現,純虛擬函式一般在基類中沒有實現。

純虛擬函式首先必須是成員函式。

純虛擬函式是虛擬函式的一種特例,具有虛擬函式的性質——通過它可以實現動態多型性。

如果在派生類中沒有對基類的純虛擬函式進行定義,那麼他在派生類中依然是純虛擬函式,派生類則依然是抽象類。

一個類如果含有純虛擬函式,那麼該類只能作為基類用於派生新類,不可以例項化。(類似與java中的介面)

抽象類主要表達一個類族的共同特徵或者行為,以方便該類族的派生類繼承和實現,從而更好的實現多型性。

不能直接用抽象類物件作為函式引數型別、函式返回值型別或顯示轉換型別。

函式引數設定為抽象基類的指標或引用時,使用抽象基類的指標或引用(指向子類)傳進去可動態繫結。

函式過載

函式名相同,但是引數表不同。

運算子過載

<函式返回值型別> operator <運算子> (<形參表>)

{

<函式體>

}

成員運算子過載,引數個數必須必運算子原來的引數個數少1,表示預設隱含的另一個引數是該類的物件,該類的物件被隱含作為第一運算元。

非成員運算子過載,引數個數與運算子原來的個數相同。<<和>>運算子只能過載為非成員運算子。

單目運算子最好過載為成員運算子,雙目運算子最好過載為非成員運算子。

過載字首++或—

<函式型別> operator ++();

過載字尾++

<函式型別> operator ++(int);             int僅作為與字首的區別

賦值運算子過載類似於拷貝建構函式

通常凡事包含動態分配成員或包含指標成員的類,都需要提供拷貝建構函式;提供拷貝建構函式的同時,還應該考慮過載賦值運算子。

呼叫拷貝建構函式的情況:

1當以物件作為函式引數,以值傳遞的方式傳入函式體時;2當以物件作為函式返回值,以值傳遞的方式從函式返回物件時;3當用物件初始化另一個物件時。