2010-08-02 102 views
3

看看這個代碼:公衆,保護私人

#include <iostream> 

using namespace std; 

class A 
{ 
private: 
    int privatefield; 
protected: 
    int protectedfield; 
public: 
    int publicfield; 
}; 

class B: private A 
{ 
private: 
    A a; 
public: 
    void test() 
    { 
     cout << this->publicfield << this->protectedfield << endl; 
    } 
    void test2() 
    { 
     cout << a.publicfield << a.protectedfield << endl; 
    } 
}; 

int main() 
{ 
    B b; 
    b.test(); 
    b.test2(); 
    return 0; 
} 

B可訪問這個 - > protectedfield但還沒有到a.protectedfield。爲什麼?然而,B是A的子類

+4

不,B不是A的子類。如果你使用公有繼承,那將是。 – 2010-08-02 14:07:00

+0

[Here](http://stackoverflow.com/questions/860339/difference-between-private-public-and-protected-inheritance-in-c/1372858#1372858)是一個解釋它是如何工作的。 – 2010-08-02 14:28:18

+0

爲什麼?私有繼承意味着所有繼承的字段和方法都將變爲私有,所以它們只能在派生類中訪問。 – l245c4l 2010-08-02 14:58:13

回答

3

B只能訪問受保護的字段本身或其他類型爲B的對象(或者如果將它們視爲B-s,則可能從B派生而來)。

B無權訪問同一繼承樹中任何其他不相關對象的受保護字段。

即使蘋果都是水果,蘋果公司也無權訪問橙子的內部。

class Fruit 
{ 
    protected: int sweetness; 
}; 

class Apple: public Fruit 
{ 
    public: Apple() { this->sweetness = 100; } 
}; 

class Orange: public Fruit 
{ 
public: 
    void evil_function(Fruit& f) 
    { 
     f.sweetness = -100; //doesn't compile!! 
    } 
}; 

int main() 
{ 
    Apple apple; 
    Orange orange; 
    orange.evil_function(apple); 
} 
+0

那麼這意味着互聯網上一半的解釋是錯誤的?因爲他們說這個子類可以訪問不真實的超類保護成員。它有權訪問它們,因爲它有正確的?所以受保護意味着它們可以複製到與公共相同的子類,但不能從課外訪問。那是對的嗎? – l245c4l 2010-08-02 14:59:45

+0

你的回答是對的,但你根本不需要蘋果課。 (正如你所說,編譯器抱怨Orange類中的受保護訪問)。只要說:橙色不能改變另一個水果的內部 - 即使它也是橙色。 – IanH 2010-08-02 15:20:31

+1

橙色可以訪問另一個橙色*的受保護的內部,如果它看到橙色*。 - 是的,在這個例子中,如果'evil_function'傳遞了一個Orange實例而不是Apple實例,它仍然是一個編譯錯誤,因爲不能保證Oranges會一直傳遞。如果'evil_function'接受了'Orange&',而不是'Fruit&',那麼修改參數的受保護成員是合法的。 – UncleBens 2010-08-02 16:59:52

3

這個 - > protectedfield:A的 乙enherits,這意味着protectedfield是其自身的屬性現在,所以它能夠訪問它。

a.protectedfield: a是B類的成員,該成員具有受保護的protectedfield變量。 B不能碰它,因爲受保護手段只能從A內訪問。

+0

受保護意味着從A和A的子類訪問。而B是A的子類。 – l245c4l 2010-08-02 14:14:44

+0

@ l245c4l:B不是A的子類,因爲您使用私有而非公共繼承。公共繼承意味着'is-a',私人繼承意味着'is-implemented-in-terms-of'。 – TheJuice 2010-08-02 14:19:12

+1

公共/私人遺產是一種紅色聽證。沒有對象間訪問權限,每個對象只將其公共接口暴露給其他對象(不管類是什麼)。友誼是顛覆訪問說明符的唯一方法。注意:X班是本身的朋友。 – 2010-08-02 14:29:55

0

讓我們打破小部分的整個代碼。複製並粘貼這兩個代碼,並嘗試編譯!!!!

#include <iostream> 
using namespace std; 
class A 
{ 
private: 
    int privatefield; 
protected: 
    int protectedfield; 
public: 
    int publicfield; 
}; 

int main() 
{ 
    A a; 
    cout<<a.publicfield; 
    cout<<a.privatefield;/////not possible ! private data can not be seen by an object of that class 
    cout<<a.protectedfield;////again not possible. protected data is like privete data except it can be inherited by another.If inherited as private then they are private,if as protected then protected and if as public then also protected. 
} 

現在乙繼承類A私有

#include <iostream> 

using namespace std; 

class A 
{ 
private: 
    int privatefield; 
protected: 
    int protectedfield; 
public: 
    int publicfield; 
}; 

class B: private A 
{ 
private: 
    A a; 
public: 
    void test() 
    { 
     cout << this->publicfield << this->protectedfield << endl; 
    } 
    void test2() 
    { 
     cout << a.publicfield << endl; 
    } 
}; 
int main() 
{ 
    /*Now B will have both public and protected data as private!!!! 
    That means 
    B now looks like this class 


    Class B 
    { 

     private: 
     int protectedfield; 
     int publicfield; 
    } 

    As we have discussed private/protected data can not be accessed by object of the class 
    so you you can not do things like this 

    B b; 
    b.protectedfield; or b.publicfield; 

    */ 
    B b; 
    b.privatefield;////Error !!! 
    b.protectedfield/////error!!!! 
} 

謝謝!