繼承與派生(一)
1.繼承的作用:
程式碼複用
繼承和派生, 基類和派生類
class Stu : public People
類標識 類名 訪問限定符 基類類名
訪問限定符一般都為public
2.派生類繼承基類的什麼東西
除了基類的構造和解構函式以外的所有成員 所以,派生類的構造需要自己實現
參考程式碼:
class Base { public: Base(int b) :mb(b){} //基類構造 void Show() { std::cout << "mb : " << mb << std::endl; } void Show(int a) { std::cout << "a : " << a << std::endl; } protected: int mb; }; class Derive :public Base { public: Derive(int d) :md(d), Base(d){} //派生類構造 void Show() { std::cout << "md : " << md << std::endl; } private: int md; }; int main() { Derive d(10); d.Base::Show(10); return 0; }
3.訪問限定符
public: 任意位置都可以訪問
protected: 本類類中,子類類中訪問
private: 本類類中訪問
3.基類中不同的訪問限定符下的成員以不同的繼承方式在派生類中的訪問限定
public protected private (訪問限定符) public public protected 不可見 protected protected protected 不可見 private private private 不可見 (繼承方式) (訪問限定)
基類的私有成員繼承了但是屬性是不可見的
protected 必須的子類的子類可訪問
4.派生類物件的構造和析構方式
派生類 (1)基類部分 (2)2派生類部分
構造 : 先基類部分 ,後派生類部分
析構 : 先派生類部分,後基類部分
系統給基類部分呼叫預設的建構函式
Derive(int d) :md(d), Base(d){}
Base(d) 在引數列表中指明瞭構造方式,帶一個引數
5.類和類的關係
組合 a part of has_a 桌子–>桌腿
繼承 a kind of is_a 鳥—>鷹
代理 (通過表層限制底層的介面,實現新的特性)
class Date
class Stu
{
private:
char* mname;
int mage;
Date birth; //物件作成員變數,組合關係
};
6.同名函式的關係
6.1 函式過載 同名,同作用域,引數列表不同
6.2 隱藏 存在但看不見
(1)繼承關係 基類和派生類同名的方法 不同作用域
(2).派生類中的同名函式隱藏了基類的所有同名函式 是在同作用域下的
6.3 覆蓋
(1).繼承關係 基類和派生類同名同參的方法 不同作用域
(2)派生類中同名同參數的虛擬函式會覆蓋基類同名同參數的虛擬函式(在編譯期間虛表覆蓋)
d.Show(); //調派生類
d.Base::Show(); //用作用域才可呼叫基類
7.基類和派生類的相互指向或者引用
允許基類指標指向派生類物件
允許基類引用派生類物件
(將派生類轉為基類,派生類是包含基類的,所以是可以的)
Base b;
Derive d;
Base* pbase2 = &d; //學生當人
Derive* pderive = &b; // 錯誤 人當學生
Base& rbase2 = b; //學生當人
Derive& rderive = d; // 錯誤 人當學生
*pbase 指標解引用是物件
8.多型 ==》 介面複用
8.1 靜多型 //編譯期間可確定函式的呼叫 靜態繫結 早繫結
8.2 動多型 //執行期間可確定函式的呼叫 動態繫結 晚繫結
8.3 過載是一種靜多型
8.4 基類中的函式是虛擬函式,派生類中同名同參的函式也是虛擬函式,vitual 給動多型提供支援
8.5 函式入口地址放在符號表中,符號表是在編譯,連結時生成,但不載入到記憶體中。
8.6 若有虛擬函式,則多一個虛擬函式指標vfptr,指向虛擬函式所放的記憶體的入口地址 入口地址存在於虛表中,虛表存在於只讀資料段(可載入到記憶體,在執行期間可等到函式的入口地址)
8.7 虛擬函式指標vfptr會合並
8.8 虛擬函式指標->虛表->rttl(執行時的型別資訊)
9.什麼情況會發生動多型的呼叫
1.指標或者引用呼叫虛擬函式
動多型-》暫存器(值在執行時才可知)
2.物件完整
構造,析構是靜多型