1. 程式人生 > >清華大學《C++語言程式設計進階》線上課程筆記06---繼承、派生、多型性

清華大學《C++語言程式設計進階》線上課程筆記06---繼承、派生、多型性

類的繼承

保持已有類的特性而構造新類的過程稱為繼承;

實現設計與程式碼的重用.

在已有類的基礎上新增自己的特性而產生新類的過程稱為派生

當新的問題出現,原有程式無法解決(或不能完全解決)時,需要對原有程式進行改造

派生類的構成

吸收基類成員

  • 預設情況下派生類包含了全部基類中除構造和解構函式之外的所有成員;
  • C++11規定可以用using語句繼承基類建構函式。

改造基類成員

  • 如果派生類聲明瞭一個和某基類成員同名的新成員,派生的新成員就隱藏或覆蓋了外層同名成員

新增新的成員

  • 派生類增加新成員使派生類在功能上有所發展

繼承方式

區別

派生類成員派生類物件對基類成員的訪問許可權

三種繼承方式的共同點:

  • 派生類中的成員函式:可以直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員(唯一的限制);
  • 對基類的private成員的唯一訪問方式就是呼叫基類自身的私有成員訪問介面,介面是public或者protected成員.

公有繼承(public)

  • 在派生類中身份不變;
  • 通過派生類的物件:只能訪問基類public成員。

私有繼承(private)

  • 全部私有化;
  • 通過派生類的物件:不能直接訪問從基類繼承的任何成員。

保護繼承(protected)

  • public成員被保護起來;
  • 通過派生類的物件:不能直接訪問從基類繼承的任何成員。

protected 成員的特點與作用

  • 對建立其所在類物件的模組來說,它與 private 成員的性質相同。
  • 對於其派生類成員函式來說,它與 public 成員的性質相同。
  • 既實現了資料隱藏,又方便繼承,實現程式碼重用。
  • 適應於基類和派生類均為同一團隊所設計時;

繼承的實用性總結:

  • 對於派生類內部來說:基類私有成員被保護了,其他的都能看;
  • 對於派生類物件來說:
  1. 能使用基類public成員------>public繼承時;
  2. 不能使用基類public成員---->private和protected繼承時;

型別轉換

公有派生類物件可以被當作基類的物件使用,反之則不可。

  • 派生類的物件可以隱含轉換為基類物件;
  • 派生類的物件可以初始化基類的引用;
  • 派生類的指標可以隱含轉換為基類的指標。

通過基類物件名、指標只能使用從基類繼承的成員。

指向基類型別的指標,你給它派生類物件的地址,只會從派生類中尋找基類傳下來的那些成員,派生類的新成員會被忽略。

派生類的建構函式

派生類的建構函式需要給基類的建構函式傳遞引數;

p.s.當基類有預設建構函式時,也可以不傳引數;
派生類名::派生類名(形參表):
基類名1(引數), 基類名2(引數), ..., 基類名n(引數),
本類成員(含物件成員)初始化列表
{
//其他初始化
};

class Derived: public Base2, public Base1, public Base3 {
public:
Derived(int a, int b, int c, int d): Base1(a), member2(d), member1(c),
Base2(b)
//此處的次序與建構函式的執行次序無關
{ }
private:
Base1 member1;
Base2 member2;
Base3 member3;
}

派生類複製建構函式

給基類傳派生類物件的引用;

Line::Line(const Line &p): Point(p) {…}

訪問從基類繼承的成員

當派生類與基類中有相同成員時:

  • 通過派生類物件使用的是派生類中的同名成員;(同名隱藏)
  • 如要通過派生類物件訪問基類中被隱藏的同名成員,應使用基類名和作用域操作符(::)來限定
// Derived 繼承自 Base1 和 Base2
Derived d;
Derived *p = &d;

d.fun();
d.Base1::fun();
p->Base2::fun();

二義性問題

  • 如果從不同基類繼承了同名成員,但是在派生類中沒有定義同名成員,“派生類物件名或引用名.成員名”、“派生類指標->成員名”訪問成員存在二義性問題;
  • 解決方式:用類名限定
Derived d;
d.Base1::fun0();
d.Base2::fun0();

虛基類

解決的問題

當派生類從多個基類派生,而這些基類又共同基類,則在訪問此共同基類中的成員時,將產生冗餘,並有可能因冗餘帶來不一致性

作用

  • 主要用來解決多繼承時可能發生的對同一基類繼承多次而產生的二義性問題
  • 為最遠的派生類提供唯一的基類成員,而不重複產生多次複製

在第一級繼承時就要將共同基類設計為虛基類

class  B...
class B1:virtual public B
class B2:virtual public B
class b:public B1,public B1
  1. 建立物件時所指定的類稱為最遠派生類;
  2. 所有派生類要在初始化列表中給虛基類傳引數;(沒傳則用預設建構函式)
  3. 在建立物件時,只有最遠派生類的建構函式呼叫虛基類的建構函式,其他類對虛基類建構函式的呼叫被忽略。
b(int var) : B(var), B1(var), B2(var)