任何人都可以向我解释为什么(例如,“为什么语言是这样的?”)以下代码在B::C::bar
的第二行有编译错误?
class A
{
public:
struct D
{
void call_foo (A &a)
{
a.foo ();
}
};
protected:
void foo () {}
};
class B : public A
{
struct C : public A::D
{
void bar (A &a, B &b)
{
b.foo (); // OK
a.foo (); // Error. Huh?
call_foo (a); // Ugly workaround
}
};
};
当且仅当基指针的类型恰好是封闭类型(而不是某些父类型)时,方法似乎可以安全地在父类中使用受保护的方法。
这似乎很奇怪。为什么这种语言会这样?
答案 0 :(得分:8)
struct C
嵌套在类B
中,它被注册为成员,因此它具有与任何其他成员相同的访问权限。所以是的,它可以访问基类protected
的{{1}}成员。但请注意,您只能通过A
类型的对象访问protected
A
成员;你不能通过B
来做到这一点。这是有道理的,因为派生类的成员应该只能访问从基类继承的A
成员;这些成员属于派生类。但是不应该允许直接访问基类的protected
成员;它们属于基类(或其他派生类)。
规则对于内部类并不特殊,对protected
的成员函数也是如此。
§11.4/1 Protected member access [class.protected]
(强调我的)
除了前面条款中描述的那些之外的附加访问检查 [class.access]在非静态数据成员或非静态时应用 member function是其命名类的受保护成员 ([class.access.base])115如前所述,访问受保护的 成员被授予,因为引用发生在朋友或成员中 一些C级。如果访问是形成指向成员的指针 ([expr.unary.op]),嵌套名称说明符应表示C或类 源自C. 所有其他访问涉及(可能是隐含的) 对象表达式([expr.ref])。在这种情况下,对象的类 表达式应为C或源自C 的类。 [实施例:
B
- 结束示例]