当我使用CRTP(奇怪地重复使用模板模式)时发现了这一点。
template <typename T>
class Base {
private:
void f() {
//when T has its own f(), it calls that
//when T doesn't have, it calls itself, which is invoked recursively
//but i expect the compiler to complain that f() is private when T doesn't have its own f()
static_cast<T*>(this)->f();
}
public:
void g() {
f();
}
};
class Derived : public Base<Derived> {};
我以为我了解public
,protected
和private
,但是对于这种情况,看来我是错的。任何解释表示赞赏!
答案 0 :(得分:1)
这仅在阴影声明为public
时有效。参见this example:
class Derived : public Base<Derived> {
private:
void f() { }
};
void x(Derived* d) {
d->g();
}
您得到:
<source>: In instantiation of 'void Base<T>::f() [with T = Derived]':
<source>:13:9: required from 'void Base<T>::g() [with T = Derived]'
<source>:23:10: required from here
<source>:8:9: error: 'void Derived::f()' is private within this context
static_cast<T*>(this)->f();
^~~~~~~~~~~
<source>:19:10: note: declared private here
void f() { }
^
如果该函数未在Derived
中隐藏,则该调用与必须合法的this->Base<Derived>::f()
相同,因为Base
是唯一可以访问它的类。 / p>
您的困惑还可能是由于访问了一个看似不同的对象而引起的。请记住,访问修饰符根据作用域而不是实例来限制访问。在Base
中声明的任何方法都可以触摸任何 Base
实例的私有成员,而不仅仅是this
的私有成员。