任何人都可以向我解释为什么(例如,"为什么语言是这样的?")以下代码在第二行有编译错误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 } }; };
当且仅当基指针的类型恰好是封闭类型(而不是某些父类型)时,似乎方法可以安全地在父类中使用受保护的方法.
这看起来很奇怪.为什么这种语言呢?
结构C
嵌套在类中B
,它被注册为成员,因此它具有与任何其他成员相同的访问权限.所以是的,它可以访问protected
基类的成员A
.但请注意,您只能通过类型对象访问protected
成员; 你不能通过一个.这是有道理的,因为派生类的成员应该只能访问从基类继承的成员; 这些成员属于派生类.但是不应该允许直接访问基类的成员; 它们属于基类(或其他派生类).A
B
A
protected
protected
规则对于内部类并不特殊,对于成员函数也是如此B
.
§11.4/ 1受保护的成员访问[class.protected]
(强调我的)
当非静态数据成员或非静态成员函数是其命名类([class.access.base])的受保护成员时,将应用超出前面在Clause [class.access]中描述的那些的附加访问检查.115如上所述之前,授予对受保护成员的访问权限,因为引用发生在某个C类的朋友或成员中.如果访问要形成指向成员的指针([expr.unary.op]),则嵌套名称说明符应表示C或从C派生的类.所有其他访问涉及(可能是隐式的)对象表达式([expr] .REF]).在这种情况下,对象表达式的类应为C或从C派生的类.[例如:
class B { protected: int i; static int j; }; class D1 : public B { }; class D2 : public B { friend void fr(B*,D1*,D2*); void mem(B*,D1*); }; ... void D2::mem(B* pb, D1* p1) { pb->i = 1; // ill-formed p1->i = 2; // ill-formed i = 3; // OK (access through this) B::i = 4; // OK (access through this, qualification ignored) int B::* pmi_B = &B::i; // ill-formed int B::* pmi_B2 = &D2::i; // OK j = 5; // OK (because j refers to static member) B::j = 6; // OK (because B?::?j refers to static member) } ...- 结束例子]