C++ 單繼承 父類和子類

1.如果派生類的繼承方式爲public,則這樣的派生類稱爲基類的子類;
2. C++ 允許父類指針指向子類對象,父類引用子類對象,無須通過強制類型轉換保持賦值類型相容,因爲子類對象isa父類對象,編譯時按父類說明的權限訪問成員;
3. 通過父類指針調用虛函數進行晚期綁定,根據對象的實際類型綁定到覈實的實例成員函數;
4. 父類指針可視爲泛型函數,配合虛函數產生多態行爲;
示例代碼
#include <iostream>

using namespace std;
class POINT{
int x, y;
public:
int getx( ){ return x; } int gety( ){ return y; }
void show( ){ cout<<"Show a point\n"; }
POINT(int x,int y): x(x), y(y){ }
};
class CIRCLE: public POINT{//公有繼承,基類和派生類構成父子關係
int r;
public:
int getr( ){ return r; } void show( ){ cout<<"Show a circle\n"; }
CIRCLE(int x, int y, int r):POINT(x,y){ CIRCLE::r=r; }
} c(3,7,8);
void main(void){
POINT *p=&c;//父類指針p指向子類對象,不用類型轉換p=(POINT*)&c
cout<<c.getr( )<<p->getx( );//不能用p->getr( ),編譯時無POINT::getr( )
p->show( ); //p指向子類對象,但調用的是POINT::show( )
}
輸出結果
r: 8 ,x: 3
show a point
5.在派生類的函數成員內部,基類指針可以直接指向該派生類對象,即對派生類的函數成員而言,基類被等同地當做派生類的父類;
6.如果一個函數聲明爲基類的友元,則友元函數內部的基類指針也可以直接指向派生類對象,即對基類的友元函數而言,基類被等同的當做派生類的父類;
7.同理,在上述兩種情況下,基類引用可直接引用派生類對象(泛型引用)。
示例代碼
#include <iostream>

using namespace std;

class VECHILE{
    int speed,weight,wheels;
    public:
    VECHILE(int spd,int wgt,int whl);
    friend void main();
};
VECHILE::VECHILE(int spd,int wgt,int whl)
{
    speed = spd;
    weight = wgt;
    wheels = whl;
}
class CAR:VECHILE{
    int seats;
    public:
    VECHILE *who();
    CAR(int sd,int wt, int st):VECHILE(sd,wt,4)
    {
        seats = st;
    }
};
VECHILE *CAR::who()
{
    VECHILE *p = this;//派生類內的基類指針直接指向派生類對象:泛型
    VECHILE &q = *this;//派生類內基類有值引用直接引用派生類對象:泛型
    return p;

}
void main(void)
{
    CAR c(1,2,3);
    VECHILE *p = &c;//編譯器報錯,不可對不可訪問的基類“VECHILE”進行轉換
    //return 0;
}
8.派生類的存儲空間
  • 派生類的成員一部分是新定義的,另一部分是從基類
    繼承而來的,在派生類對象的存儲空間中必然包含了
    基類的數據成員;
  • 在構造派生類對象之前,先構造或初始化基類對象的
    存儲空間,作爲派生類對象存儲空間的一部分;
  • 在計算派生類對象存儲空間時,基類和派生類的靜態
    數據成員
    都不應計算在內。
示例代碼
#include <iostream>

using namespace std;
class A{
    int h,i,j;
    static int k;//必須在類體外初始化
};
class B:A{
    int m,n,p;
    const static int q = 0;//const 只能在體外或者體內一處有值
};
int A::k = 0;//靜態數據成員必須初始化
int main()
{
    cout << "size of int : " << sizeof(int) << endl;
    cout << "size of A :" << sizeof(A) << endl;
    cout << " size of B :" << sizeof(B) << endl;
    system("pause");
    return 0;
}

運行結果
size of int : 4
size of A :12
 size of B :24
示例代碼
class BAG
{
    int *const e;
    const int s;
    int p;

public:
    BAG(int m) : e(new int[m]), s(e ? m : 0) { p = 0; }
    ~BAG()
    {
        if (e)
        {
            delete e;
            *(int *)&s = 0;
            *(int **)&e = 0; //0代表空指針
        }
    }
    int getp() { return p; }
    int have(int f)
    {
        for (int i = 0; i < p; i++)
        {
            if (e[i] == f)
                return 1;
            return 0;
        }
    }
};
class SET:protected BAG{//不允許重複的元素,故須覆蓋基類的pute
    public:
    BAG::getp;
    BAG::have;//從保護恢復爲public
    int pute( int f)
    {
        return have(f)?1:BAG::have(f); //不能去掉BAG::,遞歸
    }
    SET(int m):BAG(m){ } //C++缺省的析構函數~SET( )自動調用~BAG( )
};//若定義析構函數,形式爲~SET( ){ },功能同缺省析構函數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章