将自身转换为派生 class 后可以访问 C++ 基本私有方法吗?
c++ base private method can be accessed after casting itself to derived class?
我在使用 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
,但对于这种情况,看来我错了。任何解释表示赞赏!
这仅在阴影声明为 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
是唯一的 class可以访问它。
您的困惑也可能来自访问看似不同的对象。请记住,访问修饰符按范围限制访问,而不是按实例。在 Base
中声明的任何方法都可以触及 any Base
实例的私有成员,而不仅仅是 this
的私有成员。
我在使用 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
,但对于这种情况,看来我错了。任何解释表示赞赏!
这仅在阴影声明为 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
是唯一的 class可以访问它。
您的困惑也可能来自访问看似不同的对象。请记住,访问修饰符按范围限制访问,而不是按实例。在 Base
中声明的任何方法都可以触及 any Base
实例的私有成员,而不仅仅是 this
的私有成员。