1. 程式人生 > >C++(筆記)三種繼承機制

C++(筆記)三種繼承機制

在實際程式設計中其實公有繼承佔絕大多數,但其他也是都需要了解的

首先要知道子類繼承了基類的所以資料成員和全部函式成員(除了構造、析構器),但它們的繼承方式不同,訪問許可權也會不一樣

明確訪問有兩種:
1.子類中的新增成員訪問從基類繼承的成員
2.子類外部(非類族內的成員)通過子類的物件訪問從基類繼承的成員

注意:不管哪種繼承方式,子類都不能直接訪問基類的私有成員

一、public繼承(公有繼承)

基類的public和protected成員的訪問屬性在子類中不變,而基類的私有成員不可直接訪問(基類的public和protected成員做子類的public和protected成員),—基類public成員,子類可以通過子類內部訪問該成員,也可以通過子類物件(類外)訪問該成員。—基類protected成員,可以通過子類內部訪問該成員,但不能通過子類物件(外部)訪問該成員。

#include <iostream>
using namespace std;

class Point{
    public:
        void initPoint(float _x=0,float _y=0)
        {
            x=_x;
            y=_y;
        }
        void move(float offx,float offy)
        {
            x+=offx;
            y+=offy;
        }
        float getX() const
{ return x; } float gety() const { return y; } private: float x,y; }; class Rectangle:public Point{ public: void initRectangle(float _x,float _y,float _w,float _h) { initPoint(_x,_y);//類內呼叫基類成員函式
w=_w; h=_h; } float getH() const { return h; } float getW() const { return w; } private: float w,h; }; int main() { Rectangle rect; rect.initRectangle(2,3,20,10); rect.move(3,2);//類外通過物件呼叫基類成員函式 cout<<"The data of rect(x,y,w,h):"<<endl; cout<<rect.getX()<<","<<rect.gety()<<","<<rect.getW()<<","<<rect.getH()<<endl; return 0; }

這裡寫圖片描述

二、private繼承(私有繼承)

基類中的public和protected成員都以私有成員身份在子類中而基類私有私有成員不用說,在子類中肯定是不可直接訪問的,也就是說基類的public和protected成員被繼承後作為子類的私有成員,子類其他成員可以訪問,但子類物件是無法直接訪問的

若還是以上的程式碼會出現錯誤
這裡寫圖片描述
這裡寫圖片描述

move成員函式不可被訪問
getX,getY成員函式不可被訪問

只能通過類內訪問函式,不可通過子類物件訪問

#include <iostream>
using namespace std;

class Point{
    public:
        void initPoint(float _x=0,float _y=0)
        {
            x=_x;
            y=_y;
        }
        void move(float offx,float offy)
        {
            x+=offx;
            y+=offy;
        }
        float getX() const
        {
            return x;
        }
        float getY() const
        {
            return y;
        }
    private:
        float x,y;
};

class Rectangle:private Point{
    public:
        void initRectangle(float _x,float _y,float _w,float _h)
        {
            initPoint(_x,_y);//類內呼叫基類成員函式 
            w=_w;
            h=_h;
            cout<<getX()<<endl;//因為是private繼承,所以只能在類內來訪問基類函式 
            cout<<getY()<<endl;
            cout<<getW()<<endl;
            cout<<getH()<<endl;
        }
        float getH() const
        {
            return h;
        }
        float getW() const
        {
            return w;
        }

    private:
        float w,h;
};

int main()
{
    Rectangle rect;
    //rect.move(3,2);//錯誤,move函式是基類成員,通過private繼承,成為了子類的private成員,子類物件無許可權 
    cout<<"The data of rect(x,y,w,h):"<<endl;

    rect.initRectangle(2,3,20,10);
    //cout<<rect.getX()<<","<<rect.gety()<<","<<rect.getW()<<","<<rect.getH()<<endl;//同理,錯誤 
    return 0;
}

三、protected繼承(保護繼承)

基類的public和protected成員以保護成員(protected)出現在子類中,而基類私有成員還是不可直接訪問,所以子類的其他成員可以直接訪問基類繼承來的public和protected成員,但是子類物件無法直接訪問(到目前為止和private繼承相同)

四、private繼承機制與protected繼承機制區別

看了上面可能會覺得兩者完全相同,但是這只是通過一次繼承,通過一次繼承,protected和private繼承機制是完全相同的,但經過private繼承後,基類成員都成為了子類的私有成員或者不可訪問成員,若進一步派生,那就是子類成為了基類,因為前面基類的成員在子類都是私有屬性了,所以進一步派生之後私有成員都是無法直接訪問的———但是protected繼承機制在這一點若進一步派生,是protected成員被繼承,那麼protected成員還是可以通過子類內部來訪問的(不能通過子類物件訪問)——-這就是兩種繼承機制的區別