1. 程式人生 > >三種繼承方式與三種訪問許可權的相互組合

三種繼承方式與三種訪問許可權的相互組合

   
    對基類進行繼承時,三種繼承方式下,基類的三種訪問許可權在子類中會有如何的變化這個問題,本科時上C++這門課的時候曾仔細的分析並弄得挺清楚,後來時間久了、用的也不多,慢慢的又變得心裡不太有譜了。這次接著準備面試的契機,又重新仔細分析了一番,留個案底,以免再犯糊塗。

三種訪問許可權

    public:可以被任意實體訪問
    protected:只允許子類及本類的成員函式訪問
    private:只允許本類的成員函式訪問

三種繼承方式

    public 繼承  
    protect 繼承
    private 繼承

組合結果

    基類中      繼承方式             子類中

    public     & public繼承        => public
    public     & protected繼承     => protected  
    public     & private繼承      
=> private

    protected  & public繼承        => protected
   
protected  & protected繼承     => protected  
   
protected  & private繼承       => private

    private    & public繼承        => 子類無權訪問
    private  
& protected繼承     => 子類無權訪問
   
private    & private繼承       => 子類無權訪問

由以上組合結果可以看出

    1、public繼承不改變基類成員的訪問許可權
    2、private繼承使得基類所有成員在子類中的訪問許可權變為private
    3、protected繼承將基類中public成員變為子類的protected成員,其它成員的訪問       許可權不變。
    4、基類中的private成員不受繼承方式的影響,子類永遠無權訪問。

    此外,在使用private繼承時,還存在另外一種機制:准許訪問


    我們已經知道,在基類以private方式被繼承時,其public和protected成員在子類中變為private成員。然而某些情況下,需要在子類中將一個或多個繼承的成員恢復其在基類中的訪問許可權。

    C++支援以兩種方式實現該目的

    方法一,使用using 語句,這是C++標準建議使用的方式
    方法二,使用訪問宣告,形式為 base-class::member;,位置在子類中適當的訪問宣告處。(注,只能恢復原有訪問許可權,而不能提高或降低訪問許可權)

   
以下是簡單的試驗程式碼

//public.cpp

#include 
<iostream>

usingnamespace
 std;

class Grand
{
public:
    
void public_foo (){}
protected:
    
void protected_foo(){}
private:
    
void private_foo(){}
}
;

class Father:public Grand
{
public:
    
void f_public_test()        {public_foo();    }   
    
void f_protected_test()        {protected_foo(); }    
//    void f_private_test()        {private_foo();   }    
}
;

class Child:public Father
{
public:
    
void c_protected_test()        {protected_foo();  }
//    void c_private_test()        {private_foo();}
}
;


int main( int argc, char* argv[])
{
    Father  objF;

//    objF.protected_foo();

    
return1;

}


   
   

//protected.cpp

#include 
<iostream>

usingnamespace std;

class Grand
{
public:
    
void public_foo (){}
protected:
    
void protected_foo(){}
private:
    
void private_foo(){}
}
;

class Father:protected Grand
{
public:
    
void f_public_test()        {public_foo();    }   
    
void f_protected_test()        {protected_foo(); }    
//    void f_private_test()        {private_foo();   }    
}
;

class Child:public Father
{
public:
    
void c_protected_test()        {protected_foo();  }
//  void c_private_test()        {private_foo();}
}
;


int main( int argc, char* argv[])
{
    Father  objF;


//    objF.public_foo();
//    objF.protected_foo();

    
return1;

}



//private.cpp

#include 
<iostream>

usingnamespace std;

class Grand
{
public:
    
void public_foo (){}
protected:
    
void protected_foo(){}
private:
    
void private_foo(){}
}
;

class Father:private Grand
{
public:
    
void f_public_test()        {public_foo();    }   
    
void f_protected_test()        {protected_foo(); }    
//    void f_private_test()        {private_foo();   }    
}
;

class Child:public Father
{
public:
//    void c_protected_test()        {protected_foo();  }
//    void c_private_test()        {private_foo();}
}
;


int main( int argc, char* argv[])
{
    Father  objF;

//    objF.public_foo();
//    objF.protected_foo();

    
return1;

}