天天看點

C++ 公有繼承、保護繼承和私有繼承中類成員的通路權限的控制

轉自: http://blog.sina.com.cn/s/blog_b35e31b90101b6y7.html

很多同學到現在仍然對通路權限不是很清楚,或者比較模糊,有的同學記了又忘,忘了又記,是以今天想要借這篇文章給大家做一些總結,然後提供一個比較簡便的方法去記C++中的通路權限。

       衆所周知,C++通過public,protected,private三個關鍵字來實作類成員(包括成員變量和成員方法)控制通路權限,下面為了便于大家記憶,我給通路權限的大小定義: public > protected > private   > no access , 基于這個定義 給出我總結的一個小訣竅,就是: 遇升不升,遇降則降,遇平則平,私有除外 。通路權限的插圖如下:

C++ 公有繼承、保護繼承和私有繼承中類成員的通路權限的控制

為了友善大家了解,給出解釋:

       1、當成員變量在父類中的通路權限為private時,不管采用哪種繼承方式,在子類中的通路權限都變為no access,這叫 私有除外 。

       2、當成員變量在父類中的通路權限為protected時,繼承方式為public時,子類中的通路權限為protected,這叫 遇升不升 ,繼承方式為protected時,子類中的通路權限仍為protected,這叫 遇平則平 ,繼承方式為private時,子類中的通路方式變為private,這叫 遇降則降 。

       3、當成員變量在父類中的通路權限為public時,繼承方式為public時,子類中的通路權限為public, 遇平則平; 繼承方式為protected時,子類中的通路權限為protected, 遇降則降 了吧,當繼承方式為private時,子類中的通路權限為private,又 遇降則降 了吧。

       通過上面的總結我們還發現,遇降則降, 降幅總是個遇到的那個相同 ,比如public遇到了private時,通路權限就變為private,遇到protected時,就變為protected。

       明白了上面表格中的規律後,我們就可以很友善的運用這種通路權限機制來編寫程式了,在此之前我們還要了解的是,一個類成員的通路權限确定後,又對應了兩種情況,一種是在類内,一種是在類外。總結一下:

在類内部:隻要不是no access,那麼我們都可以通路該成員。也就是說類内部的通路權限比較松,凡是可通路的權限都能通路,不論是public、protected還是private。

在類外部:隻要不是public,那麼我們都不可以通路該成員。 也就是說在類的外部通路權限比較嚴格,隻要通路權限不是public的成員,在類外部都不能通路它。

明白了嗎?

為了讓大家再深刻的了解上面的總結,我還為大家設計了下面的小小的測試程式:希望用心的同學自己動手親自測試一下:

class Animal       //父類

{

public:

           void eat(){

                       cout<<"animal eat"<<endl;

           }

protected:

           void sleep(){

                       cout<<"animal sleep"<<endl;

           }

private:

           void breathe(){

                       cout<<"animal breathe"<<endl;

           }

};

class Fish:public Animal       //子類

{

public:

           void test(){

                       eat();             //此時eat()的通路權限為public,在類内部能夠通路

                       sleep();         //此時sleep()的通路權限為protected,在類内部能夠通路

                       breathe();     //此時breathe()的通路權限為no access,在類内部不能夠通路

           }

};

int main(void){

           Fish f;

           f.eat();                   //此時eat()的通路權限為public,在類外部能夠通路

           f.sleep();              //此時sleep()的通路權限為protected,在類外部不能夠通路

           f.breathe()             //此時breathe()的通路權限為no access,在類外部不能夠通路

}

上面的代碼肯定編譯出錯,希望大家把繼承方式分别更改為protected和private都測試一下,這樣你就什麼都明白了。