C++繼承與派生


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;
} 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM