c++中有兩種繼承:單一繼承和多重繼承。
對於單繼承,派生類只能有乙個基類;
對於多繼承,派生類可以有多個基類。
乙個類從多個基類派生的一般形式是:
class 類名1:訪問控制 類名2, 訪問控制 類名3 ,
..., 訪問控制 類名n
;
類名1繼承了類名2到類名n的所有資料成員和成員函式,訪問控制用於限制其後的類中的成員在類名1中的訪問許可權,其規則和單繼承情況一樣。
多繼承可以視為是單繼承的擴充套件。
派生類名::派生類名(基類形參,本類形參):基類名1(引數), 基類名2(引數), ...基類名n(引數)
;
派生類名::派生類名(基類1形參,基類2形參,...基類n形參,本類形參):基類名1(引數), 基類名2(引數), ...基類名n(引數),物件資料成員的初始化
;
1. 呼叫基類建構函式,呼叫順序按照它們被繼承時宣告的順序(從左向右)。
2. 呼叫成員物件的建構函式,呼叫順序按照它們在類中宣告的順序。
3. 派生類的建構函式體中的內容。
多繼承:例10.1
#include using namespace std;
class a
; void showa( )
};class b
void showb ( )
};class c : public a, private b
//2個基類,多繼承
void showc( )
//建構函式
int nv;
void fun()//建構函式
int nv;
void fun()//建構函式
則執行結果為
member of b0:3
member of b0:3
member of b0:3
出現這種結果是因為在建立物件時,只有最派生類的構造函式呼叫虛基類的建構函式,該派生類的其它基類對虛基類建構函式的呼叫被忽略。
#include using namespace std;
class cperson
void out();
private:
char name[8];
int num,***;
};void cperson::out()
void out();
private:
char name[8];
int num,***;
};void cperson::out()
結果:name:wu,num:1,***:男
乙個公有派生類的物件在使用上可以被當作基類的物件,反之則禁止。具體表現在:
例11.1 賦值相容規則示例
#include #include using namespace std;
class b
void show_name()
結果:zhang fang
wang ming
83768493
83768493
注意:如果希望用基類指標訪問其公有派生類的特定成員,必須將基類指標用顯式型別轉換為派生類指標。根據型別適應性的原則,乙個指向基類的指標可用來指向以公有派生的任何物件。這是是c++ 實現執行時多型性的關鍵。
多型性和虛函式
封裝性、繼承性和多型性構成了物件導向程式設計語言的三大特性。
封裝性是基礎,繼承性是關鍵,多型性是擴充。
多型性即:
即對不同類的物件發出相同的訊息將會有不同的行為。
多型從實現的角度來講可以劃分類兩類:
編譯時的多型:編譯(靜態聯編)的過程中確定操作物件的函式。編譯時多型通過函式過載和運算子過載來體現。
執行時的多型:程式執行過程(動態聯編)中才動態地確定操作物件的函式。執行時的多型通過繼承與虛函式來體現。
上述確定操作的具體物件的過程就是聯編。
虛函式允許函式呼叫與函式體的聯絡在執行時才給出。當需要同一介面、多種實現時,這種功能顯得尤其重要。
例11.2 靜態聯編示例
#include using namespace std;
class base
void print()
執行結果:
base:1
base:2
base:3
first derivation:2
second derivation:3
注意:指向基類的指標p,在執行前,p->print() 已確定為訪問基類的成員函式print()。所以不管p 指向基類,還是派生類的物件,p->print()都是基類繫結的成員函式,結果都相同。這是靜態聯編的結果。
例11.3動態聯編示例
#include using namespace std;
class base
virtual void print()//繼承是動態聯編的前提,虛函式是動態聯編的基礎。
執行結果:
base:1
first derivation:2
second derivation:3
first derivation:2
second derivation:3
注意:採用動態聯編,則隨p 指向的物件不同,使p->print() 能呼叫不同類中print()版本。即該函式呼叫依賴於執行時p 所指向的物件,具有多型性。如果是通過基類物件呼叫虛函式,不適合動態聯編。
例11.4虛函式示例
#include using namespace std;
class b0 //基類b0宣告
int main( ) //主函式
程式的執行結果為:
b0::display()
b1::display()
d1::display()
抽象類的一般形式帶有純虛函式的類稱為抽象類:
class 類名
抽象類作用:
為抽象和設計的目的而建立,將有關的資料和行為組織在乙個繼承層次結構中,保證派生類具有要求的行為。
對於暫時無法實現的函式,可以宣告為純虛函式,留給派生類去實現。
注意:1、抽象類只能作為基類來使用。
2、不能宣告抽象類的物件。
3、建構函式不能是虛函式,析構函式可以是虛函式。
例11.5純虛函式與抽象類用法示例1
b0類的display函式就是乙個純虛函式,沒有函式體,因此b0是乙個抽象類。
class b0 //抽象基類b0宣告
;class b1: public b0
int main ( ) //主函式
程式的執行結果為:
b1::display( )
d1::display( )
例11.6 純虛函式與抽象類用法示例2
#include using namespace std;
class shape
;int main()
程式的執行結果為:66
78.5398
78.5398
C 程式設計學習筆記 複習 拾遺 2
建構函式用於建立類物件,初始化其成員。析構函式用於撤銷類物件。若物件定義時若未顯式初始化,與變數類似,全域性物件和靜態物件在定義時初值為0,區域性物件在定義時初值為不確定的值。一旦建立乙個物件,物件通常都需要有乙個有意義的初值。1.在類中定義乙個具有初始化功能的成員函式。每當建立乙個物件時,就呼叫這...
C 程式設計學習筆記 複習 拾遺 3
例4.1 類中資料成員是字串 include include 字串函式宣告所在的標頭檔案 string類是c 提供的字串類,其主要功能是對字串進行操作。string類定義的變數稱為字串物件,該物件可以直接用字串常量賦值,也可呼叫string類中定義的成員函式。例4.2 連線字串例項 include ...
C 程式設計學習筆記 複習 拾遺 5
封裝性 物件的狀態資訊隱藏在物件內部,不允許外部程式直接訪問物件內部資訊,而是通過該類所提供的方法來實現對內部資訊的操作與訪問。類外如何訪問被封裝的成員 private 和 protected成員 通過物件名.公有成員函式 良好的封裝性,考慮角度 將物件的成員變數與實現細節隱藏起來,不允許外部訪問。...