在this answer对于“为什么我的对象不能访问公共(public)基类中定义的另一个对象的 protected 成员?”这个问题,可以阅读:
You can only access protected members from your own base class instance.
要么是我没有理解正确,要么是 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
实例的 protected 成员,但不能访问另一个 Base
实例的 protected 成员来自同一范围,而不管 Derived
从 Base
偏离的事实? ;博士:在这种情况下,是什么让 protected
比 private
更“私密”?
注释:
- 请不要将此问题作为链接问题的拷贝来关闭;
- 欢迎提出更好的标题建议。
最佳答案
[class.access.base] 中的规则是:
A member
m
is accessible at the point R when named in classN
if [...]
m
as a member ofN
is protected, and R occurs in a member or friend of classN
, or in a member of a classP
derived fromN
, wherem
as a member ofP
ispublic
,private
, orprotected
里面有很多字母。但基本上有两个条件:
R
是类(class)的成员或 friend 。这处理d.prot
示例 - 我们在Derived
的成员中访问Derived
的 protected 成员。R
在派生类的成员中,被访问的成员是派生类实例的成员。这处理了b.prot
示例 - 我们是派生类的成员,但prot
不是派生类的成员。
换句话说,Derived
可以访问Base
的 protected 成员——但前提是它正在访问它自己的子对象的 protected 成员。它不能访问其他 Base
对象的 protected 成员。当您认为这个其他 Base
很容易成为 SomeOtherDerived
时,这是有道理的,在这种情况下,这只是我们没有特殊访问权限的另一个不相关的对象。
关于c++ - 无法从派生类型的范围访问另一个实例的 protected 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45146025/