程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 關於C++中公有繼承、私有繼承、保護繼承的討論

關於C++中公有繼承、私有繼承、保護繼承的討論

編輯:C++入門知識

關於C++中公有繼承、私有繼承、保護繼承的討論


一、文章來由

簡單明了的理由,老生常談但是沒真正解決的問題,想搞清楚這個問題。

二、冗長的定義

我們先來看看這些冗長的定義:

公有繼承:

當類的繼承方式為公有繼承時,基類的公有成員和保護成員的訪問屬性在派生類中不變,而基類的私有成員不可直接訪問。也就是說基類的公有成員保護成員被繼承到派生類中訪問屬性不變,仍作為派生類的公有成員和保護成員,派生類的其他成員可以直接訪問它們。在類族之外只能通過派生類的對象訪問從基類繼承的公有成員。

私有繼承:

當類的繼承方式為私有繼承時,基類中的公有成員和保護成員都以私有成員的身份出現在派生類中,而基類的私有成員在派生類中不可直接訪問。也就是說基類的公有成員和保護成員被繼承後作為派生類的私有成員,派生類的其他成員可以直接訪問它們,但是在類族外部通過派生類的對象無法直接訪問它們。無論是派生類的 成員還是通過派生類的對象,都無法直接訪問從基類繼承的私有成員。

保護繼承:

保護繼承中,基類的公有成員和保護成員都以保護成員的身份出現在派生類中,而基類的私有成員變量不可直接訪問。這樣,派生類的其他成員就可以直接訪問從基類繼承來的公有和保護成員,但在類的外部通過派生類的對象無法直接訪問它們,無論是派生類的成員還是派生類的對象都無法直接訪問基類的私有成員。

三、歸納上面冗長的定義

看完冗長的定義了,其實並沒有什麼太大作用~~因為定義是獨立而嚴謹的,本來有共性的東西,沒有得到歸納和牽起聯系
好,我們來做如下歸納:

公有繼承:

1、四個字:保持原狀

2、權限:
(1)派生類成員只能訪問基類中的 public/protected 成員;
(2)派生類的對象只能訪問基類中的public成員。(注意:派生類和派生類對象是不同的)

私有繼承:

1、還是四個字:均變私有

2、權限:
(1)派生類成員也只能訪問基類中的 public/protected 成員;
(2)派生類的對象不能訪問基類中的任何的成員。

保護繼承:

1、這次字多一點:公有、保護變保護

2、權限:
(1)派生類的成員只能訪問基類中的 public/protected 成員;
(2)派生類的對象不能訪問基類中的任何的成員。

共性:

1、私有最終都是私有,且不可訪問的;
2、這就像一個權限大小包含、約束關系,仔細體會;
3、對象只有公有繼承,可以訪問 public 成員,其余的都是不能訪問的;
4、三種繼承,成員訪問都是一樣的,因為相當於基類成員被已相應的權限規則被copy到子類;
5、上面說的成員可以是:
(1)成員函數
(2)成員變量

發現還是有些太多吧,畫張圖就更明白了~~

//公有繼承【不變】               成員訪問    對象訪問
public    -->  public              Y         Y
protected -->  protected           Y         N
private   -->  private             N         N

//私有繼承                      成員訪問    對象訪問
public    -->  private             Y         N
protected -->  private             Y         N
private   -->  private             N         N

//保護繼承                      成員訪問    對象訪問
public    -->  protected           Y         N
protected -->  protected           Y         N
private   -->  private             N         N

四、例子

什麼東西最後都是要用實例說話的。

例1(針對成員函數):

下面是一道軟件設計師考試題:

已知3個類O、P、Q,類O中定義了一個私有方法 F1、一個公有方法 F2 和一個保護的方法 F3;類P和類Q是類O的派生類,其繼承方式如下所示:
(1)class P: protected O{…}
(2)class Q: public O{…}

關於方法F1的描述正確的是(B):
A、方法 F1 無法被訪問
B、只有在 類O 內才能訪問方法 F1
C、只有在 類P 內才能訪問方法 F1
D、只有在 類Q 內才能訪問方法 F1

關於方法 F2 的描述正確的是(A):【這題網上答案有是C的,個人覺得錯了】
A、類 O、P、Q 的對象都可以訪問方法 F2
B、類 P 和 Q 的對象都可以訪問方法 F2
C、類 O 和 Q 的對象都可以訪問方法 F2
D、只有在 類P 內才能訪問方法 F2

關於方法 F3 的描述正確的是(B):
A、類O、P、Q的對象都可以訪問方法 F3
B、類O、P、Q的對象都不可以訪問方法 F3 【可以毫不猶豫選出】
C、類O和Q的對象都可以訪問方法F3
D、類P和Q的對象都可以訪問方法F3

然後根據上面的信息,編寫如下代碼:

/* 
* 
* funtion: 注意,如下被注釋的代碼,都是訪問不到的
* 
* Date:2015-7-29
* 
*    Author: Bill Wang
*/

#include
using namespace std;

//在類O中分別定義了三個不同訪問類型的函數
class O{
public:
    void F2()
    {
        cout<

運行結果如下:
這裡寫圖片描述
完全印證了上面的題目和圖表~~

例2(針對成員變量):

是一樣的,詳見代碼

#include
using namespace std;

class A       //父類
{
private:
    int privatedateA;
protected:
    int protecteddateA;
public:
    int publicdateA;
};

class B :public A      //公有繼承
{
public:
    void funct()
    {
        int b;
        //b=privatedateA;   //error:基類中私有成員在派生類中是不可見的
        b=protecteddateA; //ok:基類的保護成員在派生類中為保護成員
        b=publicdateA;    //ok:基類的公共成員在派生類中為公共成員
    }
};

class C :private A  //基類A的派生類C(私有繼承)
{
public:
    void funct()
    {
        int c;
        //c=privatedateA;    //error:基類中私有成員在派生類中是不可見的
        c=protecteddateA;  //ok:基類的保護成員在派生類中為私有成員
        c=publicdateA;     //ok:基類的公共成員在派生類中為私有成員
    }
};

class D :protected A   //基類A的派生類D(保護繼承)
{
public:
    void funct()
    {
        int d;
        //d=privatedateA;   //error:基類中私有成員在派生類中是不可見的
        d=protecteddateA; //ok:基類的保護成員在派生類中為保護成員
        d=publicdateA;    //ok:基類的公共成員在派生類中為保護成員
    }
};

int main()
{
    int a; 

    B objB;
    //a=objB.privatedateA;   //error:基類中私有成員在派生類中是不可見的,對對象不可見
    //a=objB.protecteddateA; //error:基類的保護成員在派生類中為保護成員,對對象不可見
    a=objB.publicdateA;    //ok:基類的公共成員在派生類中為公共成員,對對象可見

    C objC;
    //a=objC.privatedateA;   //error:基類中私有成員在派生類中是不可見的,對對象不可見
    //a=objC.protecteddateA; //error:基類的保護成員在派生類中為私有成員,對對象不可見
    //a=objC.publicdateA;    //error:基類的公共成員在派生類中為私有成員,對對象不可見

    D objD;
    //a=objD.privatedateA;   //error:基類中私有成員在派生類中是不可見的,對對象不可見
    //a=objD.protecteddateA; //error:基類的保護成員在派生類中為保護成員,對對象不可見
    //a=objD.publicdateA;    //error:基類的公共成員在派生類中為保護成員,對對象不可見

    return 0;
}

我在寫這段代碼的時候發現了另一個問題,具體就不在這裡贅述了,一篇文章的內容不要太豐富,不然容易迷失方向,在之後的文章中分析~~~

就寫到這裡~~~

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved