无法从派生类型的范围访问另一个实例的受保护成员
Cannot access protected member of another instance from derived type's scope
在 this answer 中回答问题“为什么我的 object 不能访问另一个 object 在公共基 class 中定义的受保护成员? ", 可以阅读:
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
实例的受保护成员,但不能访问另一个 Base
实例的受保护成员来自同一范围,而不管 Derived
偏离 Base
的事实? ;博士:在这种情况下,是什么让 protected
比 private
多 "private"?
备注:
- 请不要将此问题作为链接问题的副本来关闭;
- 欢迎提出更好的标题建议。
[class.access.base]中的规则是:
A member m
is accessible at the point R when named in class N
if [...]
m
as a member of N
is protected, and R occurs in a member or friend of class N
, or in a member of a class P
derived from N
, where m
as a member of P
is public
, private
, or protected
里面有很多字母。但是基本上有两个条件:
R
是 class 的成员或朋友。这处理 d.prot
示例 - 我们在 Derived
的成员中访问 Derived
. 的受保护成员
R
在派生 class 的成员中,正在访问的成员 是 派生 class 实例的成员。这处理 b.prot
示例 - 我们在派生 class 的成员中,但 prot
不是派生 class 的成员。
换句话说,Derived
可以访问 Base
的受保护成员 - 但仅限于它正在访问其自己的子对象的受保护成员的情况。它无法访问其他 Base
对象的受保护成员。当您认为另一个 Base
很容易成为 SomeOtherDerived
时,这是有道理的,在这种情况下,这只是我们没有特殊访问权限的另一个不相关的对象。
在 this answer 中回答问题“为什么我的 object 不能访问另一个 object 在公共基 class 中定义的受保护成员? ", 可以阅读:
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
实例的受保护成员,但不能访问另一个 Base
实例的受保护成员来自同一范围,而不管 Derived
偏离 Base
的事实? ;博士:在这种情况下,是什么让 protected
比 private
多 "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 的成员或朋友。这处理d.prot
示例 - 我们在Derived
的成员中访问Derived
. 的受保护成员
R
在派生 class 的成员中,正在访问的成员 是 派生 class 实例的成员。这处理b.prot
示例 - 我们在派生 class 的成员中,但prot
不是派生 class 的成员。
换句话说,Derived
可以访问 Base
的受保护成员 - 但仅限于它正在访问其自己的子对象的受保护成员的情况。它无法访问其他 Base
对象的受保护成员。当您认为另一个 Base
很容易成为 SomeOtherDerived
时,这是有道理的,在这种情况下,这只是我们没有特殊访问权限的另一个不相关的对象。