1. 程式人生 > >C++之繼承訪問權限

C++之繼承訪問權限

父類 form 希望 style 問控制 可見性 col 多人 權限


接著上一篇總結訪問控制權限的博文,我們將上一篇遺留的繼承的訪問權限進行總結。


1、首先我先強調一個問題,子類繼承了父類除了構造函數和析構函數的所有方法和屬性。包括private修飾的屬性和方法,這一點是很重要的,有很多人認為私有的不被繼承,之所以產生這種誤區,是子類中不可用父類的私有屬性

2、類繼承後方法的屬性變化:

1、使用private繼承,父類的protected和public屬性在子類中變為private,private屬性不變。

2、使用protected繼承,父類的protected和public屬性在子類中變為protected,private屬性不變。

3、使用public繼承,父類的protected、public和private屬性不發生改變。

強調:private屬性被子類繼承,但是不能被子類使用。

1、上邊只是概括的總結了一下,下來我將分別總結一下。

(1)、對於公有繼承:

1、基類成員對其對象的可見性:

公有成員可見,其他不可見。這裏是保護成員與私有成員一樣不可見。

2、基類成員對派生類的可見性

公有成員和保護成員可見,而私有成員不可見。這裏保護成員同於公有成員一樣可見。

3、基類成員都派生對象的可見性

公有可見,其他均不可見。

也就是說,在公有繼承時,派生類的對象可以訪問基類中的公有成員;派生類的成員函數可以訪問基類中公有成員和保護成員。

4、同樣我這裏繼續給出測試驗證代碼:


class Base
{
public:
    Base():x(0),y(0),z(0)   {  }
    ~Base()    {    }
public:
    int x;
    void ShowBase()
    {
        cout<<"I am Show Base and am public"<<endl;
    }

protected:
    int y;
    void Print()
    {
        cout<<"I am Print and am protected "<<endl;
    
private:
    void Print_Private()
    {
        cout<<"I am Pint_Private"<<endl;
    }
    int z;
};
class D:public Base
{
public:
    D():a(0),b(0),c(0)   {  }
    ~D()    {    }
    int a;
    void Show_D()
    {
        cout<<"I am Show_D and public"<<endl;
        //測試公有繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試公有繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試公有繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }
    void Test()
    {
        //驗證公有繼承再保護方法中
        Print_D();
        //驗證公有繼承再私有方法中
         fun_private();
    }
protected:
    void Print_D()
    {
        cout<<"I am Print_D and am protected"<<endl;
        //測試公有繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試公有繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試公有繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }    
    int b;
private:
    void fun_private()
    {
        cout<<"I am fun_private"<<endl;
        //測試公有繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試公有繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試公有繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }
    int c;

};
void main()
{
    D d1;
    d1.Show_D();
    //子類對象可以訪問父類的公有成員
    d1.ShowBase();

}


測試結果:



技術分享圖片

對於每一種情況我都給出了測試案例,並且在測試代碼中盡可能多按照我的理解寫上了註釋。


2、對於保護繼承:

1、基類成員對其對象的可見性

公有成員可見,其他不可見。這裏是保護成員與私有成員一樣不可見。

2、基類成員對派生類的可見性

公有成員和保護成員可見,而私有成員不可見。這裏保護成員同於公有成員一樣可見。

3、基類成員都派生對象的可見性

公有可見,其他均不可見。

4、同樣我這裏繼續給出測試驗證代碼:


class Base
{
public:
    Base():x(0),y(0),z(0)  {    }
    ~Base()   {   }
public:
    int x;
    void ShowBase()
    {
        cout<<"I am Show Base and am public"<<endl;
    }
protected:
    int y;
    void Print()
    {
        cout<<"I am Print and am protected "<<endl;
    }
private:
    void Print_Private()
    {
        cout<<"I am Pint_Private"<<endl;
    }
    int z;

};
class D:protected Base
{
public:
    D():a(0),b(0),c(0)  {   }
    ~D()  {  }
    int a;
    void Show_D()
    {
        cout<<"I am Show_D and public"<<endl;
        //測試保護繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試保護繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試保護繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }
    void Test()
    {
        //驗證保護繼承再保護方法中
        Print_D();
        //驗證保護繼承再私有方法中
         fun_private();
    }
protected:
    void Print_D()
    {
        cout<<"I am Print_D and am protected"<<endl;
        //測試保護繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試保護繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試保護繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }  
    int b;
private:
    void fun_private()
    {
        cout<<"I am fun_private"<<endl;
        //測試保護繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試保護繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試保護繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }
    int c;
};


void main()
{
    D d1;
    d1.Show_D();
    //子類對象可以訪問父類的公有成員
    //d1.ShowBase();

運行結果:


技術分享圖片


3、對於私有繼承

1、基類成員對其對象的可見性:

公有成員可見,其他不可見。

2、基類成員對派生類的可見性

公有成員和保護成員可見,而私有成員不可見。這裏保護成員同於公有成員一樣可見。

3、基類成員都派生對象的可見性

所有成員均不可見。

也就是說,私有繼承,基類成員的只能由直接派生類訪問,而無法再往下繼續訪問。

4、同樣我這裏也給出測試代碼:


class Base
{

public:
    Base():x(0),y(0),z(0)
    {
    }
    ~Base()
    {

    }
public:
    int x;
    void ShowBase()
    {
        cout<<"I am Show Base and am public"<<endl;
    }

protected:
    int y;
    void Print()
    {
        cout<<"I am Print and am protected "<<endl;
    }

private:
    void Print_Private()
    {
        cout<<"I am Pint_Private"<<endl;
    }
    int z;

};


class D:private Base
{

public:
    D():a(0),b(0),c(0)
    {

    }

    ~D()
    {

    }
    int a;
    void Show_D()
    {
        cout<<"I am Show_D and public"<<endl;
        //測試私有繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試私有繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試私有繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }


    void Test()
    {
        //驗證私有繼承再保護方法中
        Print_D();
        //驗證私有繼承再私有方法中
         fun_private();
    }
protected:
    void Print_D()
    {
        cout<<"I am Print_D and am protected"<<endl;
        //測試私有繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試私有繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試私有繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }

    
    int b;
private:
    void fun_private()
    {
        cout<<"I am fun_private"<<endl;
        //測試私有繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 10;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試私有繼承時,父類的保護方法和屬性
        Print();
        y = 20;
        cout<<"Base's y = "<<y<<endl;
        //測試私有繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 30;
        //cout<<"Base's z = "<<z<<endl;
    }
    int c;

};



    class C:public D
    {
    public:
        C(){}
        ~C(){}
        void c_fun()
        {
        cout<<"I am  c_fun  and public"<<endl;
        //測試繼承時,父類的公有方法和屬性
        ShowBase();   //父類的公有方法
        x = 100;           //父類的公有屬性
        cout<<"Base's x = "<<x<<endl;
        //測試保護繼承時,父類的保護方法和屬性
        Print();
        y = 200;
        cout<<"Base's y = "<<y<<endl;
        //測試保護繼承時,父類的私有方法和屬性
        //Print_Private();
        //z = 300;
        //cout<<"Base's z = "<<z<<endl;
        }
    protected:    
    private:
    };


void main()
{
    D d1;
    d1.Show_D();
    C c1;
    //保護繼承時,當再次被繼承時,即使時公有繼承,對象將不能再訪問
    //c1.ShowBase();
    //子類對象可以訪問父類的公有成員
    //d1.ShowBase();
}

測試結果:


技術分享圖片

細心同學就會發現,私有繼承和保護繼承的測試結果不是一樣嗎?事實上是不一樣的,我在私有繼承的測試代碼中再加了一個類,C類,並且C類繼承於D類,我們可以從測試結果中看出,當D類私有繼承時,C類將不能訪問Base類的任何成員,當然C類的對象更不能訪問,而如果D類保護繼承與Base時,C類可以訪問Base的公有、保護成員,當然對象也不能訪問。


以上就是筆者對繼承中訪問控制權限的理解,並且給出了測試代碼幫助理解,希望可以幫助到大家。


C++之繼承訪問權限