2017-08-22 114 views
0

我在一個線程中遇到以下響應:C++訪問說明符理解

受保護的成員可以從派生類訪問。私人不能。

class Base { 

private: 
    int MyPrivateInt; 
protected: 
    int MyProtectedInt; 
public: 
    int MyPublicInt; 
}; 

class Derived : Base 
{ 
public: 
    int foo1() { return MyPrivateInt;} // Won't compile! 
    int foo2() { return MyProtectedInt;} // OK 
    int foo3() { return MyPublicInt;} // OK 
}; 

class Unrelated 
{ 
private: 
    Base B; 
public: 
    int foo1() { return B.MyPrivateInt;} // Won't compile! 
    int foo2() { return B.MyProtectedInt;} // Won't compile 
    int foo3() { return B.MyPublicInt;} // OK 
}; 

...

1)我的問題是: 我已閱讀:「一類的派生列表名稱的一個或多個基類和具有如下形式:

類derived-類:訪問說明符基類

其中訪問說明符是public,protected或private之一,base-class是以前定義的類的名稱,如果不使用access-specifier,是私人默認。 「和」私有繼承:當從私有基類派生時,基類的公共和受保護成員成爲派生類的私有成員。

所以......在我們的例子類派生:基本等同於類派生:因爲沒有訪問符已定義的私有基地,但代碼工作作爲作家說,所以我是什麼缺少? - 我認爲該類的派生訪問說明符的基類是私有因此,公共和受保護的成員的基礎應該是私有的類Derived並且不能訪問......謝謝!

+1

你在混淆概念。訪問說明符有兩種不同的相關性。第一個與方法有關,它是什麼類可以「查看」哪些基類方法。第二個涉及繼承,這會影響行爲,如轉換爲基類/派生類。 – CoryKramer

+1

'Base'是'Derived'的私有基類。一個班級可以訪問自己的基地(就像其成員一樣),無論他們是私人的,公共的還是受保護的。 (否則一個私人基類將是一個非常無用的東西)。其他類無法通過「派生」對象訪問「Base」,因爲它是私有的。 –

+1

請注意,儘管'private'是默認的,「繼承」通常是指「公共」繼承 – user463035818

回答

0

它的類似這種想法並不適用於你可以訪問的類的成員,它適用於你可以訪問的基類。

class A 
{ 
public: 
    void f(); 
}; 



class B : public A 
{ 
public: 
    void g() 
    { 
     f(); // OK 
     A *a = this; // OK 
    } 
}; 
class B2 : public B 
{ 
public: 
    void h() 
    { 
     f(); //OK 
     A *a = this; // OK 
    }; 
}; 
B b; 
A& ba = b; 


class C : protected A 
{ 
public: 
    void g() 
    { 
     f(); // OK, can access protected base 
     A *a = this; // OK, can access protected base 
    } 
}; 
class C2 : public C 
{ 
public: 
    void h() 
    { 
     f(); // OK, can access protected base 
     A *a = this; // OK, can access protected base 
    }; 
}; 
C c; 
c.f(); // Not OK, allthough A::f() is public, the inheritance is protected. 
A& ca = c; // Not OK, inheritence is protected. 




class D : private A 
{ 
public: 
    void g() 
    { 
     f(); // OK because A is a base of D 
     A *a = this; 
    } 
}; 
class D2 : public D 
{ 
public: 
    void h() 
    { 
     f(); //Not OK, A is inherited with private in D 
     A *a = this; //Not OK 
    }; 
}; 
D d; 
d.f(); // Not OK, allthough A::f() is public, the inheritance is private. 
D& da = d; // Not OK, inheritence is private.