2017-07-17 66 views
2

访问另一个实例的保护成员在this answer问题“?共同基类中定义另一个对象为什么不是我的对象访问保护成员”,一个可以读取:不能从派生类型的范围

您只能从您自己的基类实例访问受保护的成员。

要么我没有正确地得到它或following MCVE (live on coliru)证明她错了:

struct Base   { void f(); protected: int prot; }; 
struct Derived : Base { void g(); private: int priv; }; 

void Base::f() 
{ 
    Base b; 
    b.prot = prot; 
    (void) b; 
} 

void Derived::g() 
{ 
    { 
     Derived d; 
     (void) d.priv; 
    } 

    { 
     Derived& d = *this; 
     (void) d.priv; 
    } 

    { 
     Derived d; 
     (void) d.prot; // <-- access to other instance's protected member 
    } 

    { 
     Derived& d = *this; 
     (void) d.prot; 
    } 

    // --- 

    { 
     Base b; 
     (void) b.prot; // error: 'int Base::prot' is protected within this context 
    } 

    { 
     Base& b = *this; 
     (void) b.prot; // error: 'int Base::prot' is protected within this context 
    } 
} 

在两个错误,我得到想知道的光:我为什么能访问到另一个Derived实例的保护成员从Derived的范围,但无法从相同范围访问另一个Base实例的受保护成员,而不管Derived是否从Base开始? TL;博士:在这种情况下,protectedprivate更“私人”吗?

  • 请不要关闭这个问题作为链接的问题的重复;
  • 更好的标题建议是受欢迎的。
+0

即使您*在范围内查看对象*,访问说明符的作用相同。你使用'Base'引用,这就是她写的全部内容。 – StoryTeller

回答

2

[class.access.base]中的规则是:

当类N如果命名为A构件m是在点- [R访问[...]

  • m作为成员的N受保护,并且R发生在类N的成员或朋友中,或在成员从N,其中m推导的P成员的类P的r是publicprivate,或者protected

有很多的在那里字母。但基本上有两个条件:

  1. R是在类的成员或朋友。这处理​​示例 - 我们在Derived的成员中,同时访问Derived的受保护成员。
  2. R是派生类的成员,正在访问的成员是派生类实例的成员。这处理了b.prot示例 - 我们处于派生类的成员中,但prot不是派生类的成员。

换句话说,Derived可以访问Base的保护成员 - 但只有在它正在访问自己的子对象的保护成员的情况。它不能访问其他Base对象的受保护成员。当你认为这个其他Base很容易成为SomeOtherDerived时,这是有道理的,在这种情况下,这只是另一个与我们无关的对象,我们没有特殊的访问权限。

+0

这个答案证实了'protected'访问说明符不像'private'和'public'那么简单! – YSC