1、繼承&派生
在定義一個新的類B時,若該類與某個已有的類A相似(B擁有A的全部特點),則可以將A作為一個基類,把B作為基類的一個派生類(子類)。
在派生類的各個成員函數中,不能訪問基類中的private成員。
class 派生類名:public 基類名 { };
派生類對象的體積,等於基類對象的體積+派生類對象自己的成員變量的體積。
在派生類對象中,包含着基類對象,且基類對象的存儲位置位於派生類對象新增的成員變量之前。
2、繼承&復合
繼承:“是”關系。
– 基類 A,B是基類A的派生類。
– 邏輯上要求:“一個B對象也是一個A對象”。
• 復合:“有”關系。
– 類C中“有”成員變量k,k是類D的對象,則C和D是復合關系
– 一般邏輯上要求:“D對象是C對象的固有屬性或組成部分”。
class CMaster; //CMaster必須提前聲明,不能先寫CMaster類后寫Cdog類 class CDog { CMaster * pm; }; class CMaster { CDog * dogs[10]; };
3、訪問范圍說明符
(1)private:
可以被:基類的成員函數、基類的友元函數訪問。
(2)public:
可以被:基類的成員函數、基類的友元函數、派生類的成員函數、派生類的友元函數、其它函數訪問。
(3)protected
可以被:基類的成員函數、基類的友元函數訪問,且派生類的成員函數可以訪問當前對象的基類的保護成員。
class Father { private: int nPrivate; //私有成員 public: int nPublic; //公有成員 protected: int nProtected; // 保護成員 }; class Son : public Father { void AccessFather () { nPublic = 1; // ok; nPrivate = 1; // wrong nProtected = 1; // OK, 訪問從基類繼承的protected成員 Son f; f.nProtected = 1; //wrong, f不是當前對象 } }; int main(){ Father f; Son s; f.nPublic = 1; // Ok s.nPublic = 1; // Ok f.nProtected = 1; // error f.nPrivate = 1; // error s.nProtected = 1; //error s.nPrivate = 1; // error return 0; }
4、派生類的構造函數
(1)在執行派生類構造函數之前先執行基類構造函數。
構造函數名(形參表): 基類名(基類構造函數實參表)
{
}
顯式方式: 派生類的構造函數中為基類的構造函數提供參數
derived::derived(arg_derived-list):base(arg_base-list)
隱式方式:派生類的構造函數中, 省略基類構造函數時,派生類的構造函數, 自動調用基類的默認構造函數
派生類的析構函數被執行時, 執行完派生類的析構函數后, 自動調用基類的析構函數。
(2)包含成員對象的派生類的構造函數
class Skill { public: Skill(int n) { } }; class FlyBug: public Bug { int nWings; Skill sk1, sk2; public: FlyBug(int legs, int color, int wings); }; FlyBug::FlyBug( int legs, int color, int wings): Bug(legs, color), sk1(5), sk2(color) { nWings = wings; }
創建派生類的對象時, 執行派生類的構造函數之前:
• 調用基類的構造函數,初始化派生類對象中從基類繼承的成員
• 調用成員對象類的構造函數,初始化派生類對象中成員對象
• 執行完派生類的析構函數后:先調用成員對象類的析構函數,再調用基類的析構函數。析構函數的調用順序與構造函數的調用順序相反。
5、public繼承的賦值兼容規則
class base { }; class derived : public base { }; base b; derived d;
(1)派生類的對象可以賦值給基類對象
b = d;
(2)派生類對象可以初始化基類的引用
base &br = d;
(3)派生類對象的地址可以復制給基類指針
base *pb = &d;
Note:若protected或private繼承,則不成立。
6、直接基類與間接基類
聲明派生類時,只需要列出其直接基類。
派生類的成員包括:派生類自己定義的成員,直接基類中的所有成員、所有間接基類里的全部成員。
#include <iostream> using namespace std; class Base { public: int n; Base(int i):n(i) { cout << "Base " << n << " constructed" << endl; } ~Base() { cout << "Base " << n << " destructed" << endl; } }; class Derived:public Base { public: Derived(int i):Base(i) { cout << "Derived constructed" << endl; } ~Derived() { cout << "Derived destructed" << endl; } }; class MoreDerived:public Derived { public: MoreDerived():Derived(4) { cout << "More Derived constructed" << endl; } ~MoreDerived() { cout << "More Derived destructed" << endl; } }; int main() { MoreDerived Obj; return 0; }