在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;博士:在这种情况下,protected
比private
更加“私密”的原因是什么?
备注:
答案 0 :(得分:3)
[class.access.base]中的规则是:
如果[...]
,则在{em> R 点可以访问成员m
N
作为m
的成员受到保护,而 R 出现在班级N
的成员或朋友中,或者出现在班级成员中来自N
的{{1}}P
N
成员为m
,P
或public
那里有很多信件。但基本上有两个条件:
private
是该班级的成员或朋友。这会处理protected
示例 - 我们在访问R
的受保护成员时属于d.prot
成员。Derived
位于派生类的成员中,被访问的成员是派生类实例的成员。这处理Derived
示例 - 我们是派生类的成员,但R
不是派生类的成员。 换句话说,b.prot
可以访问prot
的受保护成员 - 但仅限于访问其自己的子对象的受保护成员的情况。它无法访问其他Derived
对象的受保护成员。如果您认为其他Base
可能很容易Base
,这是有道理的,在这种情况下,这只是我们没有特殊访问权限的另一个无关对象。