C 繼承與派生

2022-04-19 19:59:39 字數 3438 閱讀 4224

子承父業,可以使子類站在更高的基礎上,節省更多的精力。

解決原有類解決不了的問題

繼承來的資料結構應該怎麼用?

派生類怎麼初始化?

組合與繼承?————多種形式的構造

繼承來的衝突?

繼承和派生是同一過程從兩個角度(子類、基類)看。

乙個多繼承示例

class derived: access-specifier1 base1, access-specifier2 base2

;

確定繼承來的成員在派生類中的訪問許可權。

(幾乎不用private和protected)

訪問形式

public

protected

private

反身訪問yy

y派生類->基類yy

n外部物件yn

n這是類的定義(private成員只能通過類的本尊進行訪問)。

基類的private成員永不可呼叫。(封裝的實質)

從外部利用派生類物件(直接呼叫)訪問基類時,只能訪問public成員。(這與類的訪問是一致的。)

補充public最隨和,任何成員的訪問屬性不變。

保護繼承其次,在繼承的時候,僅將public改成protected。

private……全部改成private

第二條給出了一種可以從外部訪問基類保護成員的方法。即利用派生類的public介面呼叫基類

class a ;

class b ;

class c : public a, private b ;

void a::seta(int x)

void b::setb(int x)

void c::setc(int x, int y, int z)

int main()

這個錯誤的原因就是c對b類的繼承是private繼承。所以不能呼叫。

這個例子是派生類訪問基類許可權的集中體現。

通過基類物件名、指標只能使用從基類繼承的成員。這告誡我們,不要定義與繼承而來的函式同名的非虛函式,它們是invalid的。如下的例子:

#include using namespace std;

class base1

};class base2: public base1

};class derived: public base2

};void fun(base1 *ptr)

int main()

輸出結果

base1::display()

base1::display()

base1::display()

這表明,我們在派生類中定義的函式都沒有發揮作用。

一般是不繼承建構函式的。

為了實現子承父業的初衷,我們可以使用基類的建構函式,比如

class derived: public base;

}

或者在新成員並不多的情況下

class derived : public base;

private:

int a;

};

但c++11可以利用using base::base語句進行繼承。這個語句的好處還在於避免了需要寫多個建構函式的情況。

derived::derived(param_list):

base1(param), base2(param), ..., basen(param),

other_param

;繼承構造

(按照從基類繼承向下的)順序呼叫基類建構函式。可以在沒有有參時隱式呼叫無參建構函式(幾個討論見下)。

成員構造

對初始化列表中的成員進行初始化。

建構函式的構造

執行派生類的建構函式體中的內容。

在建立子類物件時候,如果子類的建構函式沒有顯示呼叫父類的建構函式且父類自己提供了無參建構函式,則會呼叫父類自己的無參建構函式。

主要是需要考慮已經定義過有參的情況,這時會找不到無參建構函式而報錯

乙個關於無參建構函式的有趣例子

class base;

int b;

};class derived : public base;

ostream &operator<<(ostream &os, const derived &d)

int main()

這裡建立物件,會呼叫父類的無參建構函式,而其實它已經因為有參建構函式的定義而刪除了,報錯為the default constructor of "derived" cannot be referenced -- it is a deleted function

這裡是清華鄭莉老師的乙個很有益的例子:

#include using namespace std;

class base1

};class base2

};class base3

};class derived: public base2, public base1, public base3

private:

base1 member1;

base2 member2;

base3 member3;

};int main()

輸出結果

constructing base2 2

constructing base1 1

constructing base3 *

constructing base1 3

constructing base2 4

constructing base3 *

對派生類的建構函式的說明:

順序:繼承順序。

無複製建構函式時呼叫無參。

相比建構函式,由於不需要傳引數,所以比較簡單。

先構造,後析構。

派生類中定義與基類中同名成員:預設呼叫派生類

從不同基類繼承了同名成員,但是在派生類中沒有定義同名成員:必須用類名+作用域分辨符"::"限定

最遠基類中成員在繼承過程當中可能出現冗餘的現象,這不僅是二義性的問題,我們以下可以專門來討論解決這個問題的機制:虛基類

利用virtual關鍵字說明基類繼承方式

class b1:virtual public b
虛基類的成員是由最遠派生類的建構函式通過呼叫虛基類的建構函式進行初始化的。

構造順序仍然是從最遠基類到最遠派生類。

但是這個機制慎用於公共工程、類庫等

C 繼承與派生

派生新類 吸收已有類的成員 調整已有類成員和新增新的成員 class 派生類名 繼承方式 基類名1,繼承方式 基類名2,派生類成員宣告 繼承方式有 public protected private 預設 公有繼承 基類的公有和保護乘員的訪問屬性在派生類中不變,基類的私有成員不能直接訪問 型別相容規則...

c 繼承與派生

繼承 與派生 一 派生方式的不同的表現 1 派生類在類內成員對基類成員 的訪問許可權 2 派生類的物件對基類成員的訪問許可權。二 公有繼承 1 基類protected和public的成員在派生類中訪問屬性保持不變 2 基類的private成員在派生類中不可訪問。3 派生類的成員 即派生類內 可以直接...

c 繼承與派生

一 基本概念 1 類的繼承,是新的類從已有類那裡得到已有的特性。或從已有類產生新類的過程就是類的派生。原有的類稱為基類或父類,產生的新類稱為派生類或子類。2 派生類的宣告 class 派生類名 繼承方式 基類名1,繼承方式 基類名2,繼承方式 基類名n 3 乙個派生類可以同時有多個基類,這種情況稱為...