C++中的繼承

技術交流QQ群:1027579432,歡迎你的加入!

1.Cpp中的繼承

  • 面向對象程序設計中最重要的一個概念是繼承。繼承允許我們依據(jù)另一個類來定義一個類,這使得創(chuàng)建和維護一個應用程序變得更容易。這樣做,也達到了重用代碼功能和提高執(zhí)行時間的效果。當創(chuàng)建一個類時,您不需要重新編寫新的數(shù)據(jù)成員和成員函數(shù),只需指定新建的類繼承了一個已有的類的成員即可,這個已有的類稱為基類,新建的類稱為派生類。繼承代表了is a關系。例如,哺乳動物是動物,狗是哺乳動物。因此,狗是動物。

2.基類&派生類

  • 一個類可以派生自多個類,這意味著,它可以從多個基類繼承數(shù)據(jù)和函數(shù)。定義一個派生類,我們使用一個類派生列表來指定基類。類派生列表以一個或多個基類命名,形式如下:
        class derived-class: access-specifier base-class
    
    • 訪問修飾符access-specifier: public、protected 或 private 其中的一個,默認是private
    • base-class: 基類的名字
    • derived-class: 派生類的名字
  • 繼承的實例如下:
        #include "iostream"
    
        using namespace std;
    
    
        class Shape{
            public:
                void setWidth(int w){
                    width = w;
                }
                void setHeight(int h){
                    height = h;
                }
            protected:
                int width;
                int height;
        };
    
        class Rect: public Shape{
            public:
                int getArea(){
                    return width * height;
                }
        };
    
        int main(){
            Rect r1;
            r1.setWidth(3);
            r1.setHeight(4);
            cout << "r1對象的面積是: " << r1.getArea() << endl;
            return 0;
        }
    

3.訪問控制和繼承

  • 派生類可以訪問基類中所有的非私有成員。因此基類成員如果不想被派生類的成員函數(shù)訪問,則應在基類中聲明為private??梢愿鶕?jù)訪問權限總結出不同的訪問類型,如下所示:
    訪問控制和繼承.png
  • 一個派生類繼承了所有的基類方法,但下列情況除外:
    • 基類的構造函數(shù)、析構函數(shù)和拷貝構造函數(shù);
    • 基類的重載運算符;
    • 基類的友元函數(shù).

4.繼承類型

  • 當一個類派生自基類,該基類可以被繼承為public、protected或private幾種類型。繼承類型是通過上面講解的訪問修飾符 access-specifier來指定的。幾乎不使用protected或private繼承,通常使用public繼承。當使用不同類型的繼承時,遵循以下幾個規(guī)則:
    • 公有繼承(public):基類中所有 public 成員在派生類中為 public 屬性;基類中所有 protected 成員在派生類中為 protected 屬性;基類中所有 private 成員在派生類中不能使用。基類的私有成員不能直接被派生類訪問,但是可以通過調用基類的公有和保護成員來訪問
    • 保護繼承(protected):基類中的所有 public 成員在派生類中為 protected 屬性;基類中的所有 protected 成員在派生類中為 protected 屬性;基類中的所有 private 成員在派生類中不能使用。
    • 私有繼承(private):基類中的所有 public 成員在派生類中均為 private 屬性;基類中的所有 protected 成員在派生類中均為 private 屬性;基類中的所有 private 成員在派生類中不能使用。
  • 基類的 private 成員不能在派生類中使用,并沒有說基類的 private 成員不能被繼承。實際上,基類的 private 成員是能夠被繼承的,并且(成員變量)會占用派生類對象的內存,它只是在派生類中不可見,導致無法使用罷了。private 成員的這種特性,能夠很好的對派生類隱藏基類的實現(xiàn),以體現(xiàn)面向對象的封裝性。
  • 使用 using 關鍵字可以改變基類成員在派生類中的訪問權限,例如將 public 改為 private、將 protected 改為 public。using 只能改變基類中 public 和 protected 成員的訪問權限,不能改變 private 成員的訪問權限,因為基類中 private 成員在派生類中是不可見的,根本不能使用,所以基類中的 private 成員在派生類中無論如何都不能訪問。

5.多繼承

  • 多繼承即一個派生類可以有多個基類,它繼承了多個基類的特性,C++類可以從多個類繼承成員,語法如下:
        class 派生類名:繼承方式1 基類名1, 繼承方式2,基類名2,.....{
            派生類的主體
        };
    
  • 其中,訪問修飾符繼承方式是public、protected 或 private其中的一個,用來修飾每個基類,各個基類之間用逗號分隔,實例如下:
        // 多繼承
        class Shape{
            public:
                void setWidth(int w){
                    width = w;
                }
                void setHeight(int h){
                    height = h;
                }
            protected:
                int width;
                int height;
        };
    
        class Rect: public Shape{
            public:
                int getArea(){
                    return width * height;
                }
        };
    
    
        
        class PaintCost{
            public:
                int getCost(int area){
                    return area * 66;
                }
        };
    
    
    
        class D: public Shape, public PaintCost{
            public:
                int getArea(){
                    return width * height;
                }
        };
    
        int main(){
            D d;
            int area;
            d.setWidth(4);
            d.setHeight(5);
            area = d.getArea();
            cout << "總面積是: " << d.getArea() << endl;
            cout << "總代價是: " << d.getCost(area) << endl; 
            return 0;
        }
    
  • 環(huán)狀繼承,如A->D,B->D,C->(A,B),如下所示:
        class D{.....};
        class A: public D{......};
        class B: public D{......};
        class C: public A, public B{.....};
    
  • 上面的繼承方法會使D創(chuàng)建兩個對象,要解決上面問題就要用虛擬繼承格式,格式是: class 派生類名: virtual 繼承方式 基類名
        class D{.....};
        class A: virtual public D{......};
        class B: virtual public D{......};
        class C: public A, public B{......};
    
  • 虛繼承: 在創(chuàng)建父類對象的時候會創(chuàng)建一個虛表,實例如下:
        // 虛繼承
        class D{
            public:
                D(){
                    cout << "D對象的構造函數(shù)\n";
                }
                ~D(){
                    cout << "D對象的析構函數(shù)\n";
                }
            protected:
                int d;
        };
    
        class B: virtual public D{
            public:
                B(){
                    cout << "B對象的構造函數(shù)\n";
                }
                ~B(){
                    cout << "B對象的析構函數(shù)\n";
                }
            protected:
                int b;
        };
    
        class A: virtual public D{
            public:
                A(){
                    cout << "A對象的構造函數(shù)\n";
                }
                ~A(){
                    cout << "A對象的析構函數(shù)\n";
                }
            protected:
                int a;  
        };
    
        class C: public A, public B{
            public:
                C(){
                    cout << "C對象的構造函數(shù)\n";
                }
                ~C(){
                    cout << "C對象的析構函數(shù)\n";
                }
            protected:
                int c;
        };
    
        int main(){
            C c; // D B A C
            cout << "sizeof(c) = " << sizeof(c) << endl;
            return 0;
        }
    

6.繼承中注意的知識點

  • 派生類構造函數(shù)的調用順序:
    • 基類的構造函數(shù)
    • 子對象類的構造函數(shù)
    • 派生類的構造函數(shù)
  • 派生類的構造函數(shù)的初始化列表中,可以包含:
    • 基類的構造函數(shù)
    • 派生類中子對象的初始化
    • 派生類中一般數(shù)據(jù)成員的初始化
  • 解釋:派生類中的基類子對象和子對象必須初始化,初始化在派生類的構造函數(shù)的初始化列表中,如果初始化列表中沒有進行初始化,則調用缺省的構造函數(shù)進行初始化?;愖訉ο蟪跏蓟瘧撛诨惖臉嬙旌瘮?shù)中完成
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容