考虑
class A {
protected:
int m;
};
class B : public A {
void foo(A& a) {
a.m = 42; // ill-formed
}
void bar(A& a) {
auto pm = &B::m;
auto pm2 = static_cast<int A::*>(pm);
a.*pm2 = 42; // is this ok?
}
};
尝试访问A::m
根据 [class.protected],直接是格式错误的。然而,似乎我们总是可以(?)使用 static_cast
来规避这个问题。 ,它允许使用指向成员的指针进行派生到基的强制转换。或者这就是UB?
[Coliru link显示bar
编译]
最佳答案
是的,您可以使用static_cast
以这种方式绕过 protected 机制。
我认为在这种特殊情况下这不是未定义的行为。
通过使用static_cast
,你告诉编译器两件事:
您要求编译器将
B
指针转换为A
指针。你告诉编译器这样做是可以的。
对于1.,编译器对这是否可以进行非常有限的检查,对于static_cast
,它允许从派生类型转换为基类型,反之亦然,仅此而已。所以编译器很高兴。变量或指针是 protected 还是公共(public)的,不是变量或指针类型的一部分。 pm
和 pm2
都不携带 protected
信息。
对于 2. 编译器完全让您自行决定这在您的设计中是否可行。这不是未定义的行为。这可能仍然不是一个好主意。 pm2
只是一个指向 A
中 int 的指针。您可以将其重置为指向 A
中公共(public)的不同 int
的指针。
背景是 C++ 中的访问控制通常是按类进行的,此外还有一些围绕 protected
的额外规则,这些规则尝试在每个实例的基础上提供某种级别的访问控制,但是这种保护正如您在有趣的问题中所证明的那样,并不完美。
关于c++ - 可以使用 static_cast 破坏 protected 成员访问检查吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54700439/