c++ - 可以使用 static_cast 破坏 protected 成员访问检查吗?

标签 c++ language-lawyer

考虑

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,你告诉编译器两件事:

  1. 您要求编译器将 B 指针转换为 A 指针。

  2. 你告诉编译器这样做是可以的。

对于1.,编译器对这是否可以进行非常有限的检查,对于static_cast,它允许从派生类型转换为基类型,反之亦然,仅此而已。所以编译器很高兴。变量或指针是 protected 还是公共(public)的,不是变量或指针类型的一部分。 pmpm2 都不携带 protected 信息。

对于 2. 编译器完全让您自行决定这在您的设计中是否可行。这不是未定义的行为。这可能仍然不是一个好主意。 pm2 只是一个指向 A 中 int 的指针。您可以将其重置为指向 A 中公共(public)的不同 int 的指针。

背景是 C++ 中的访问控制通常是按类进行的,此外还有一些围绕 protected 的额外规则,这些规则尝试在每个实例的基础上提供某种级别的访问控制,但是这种保护正如您在有趣的问题中所证明的那样,并不完美。

关于c++ - 可以使用 static_cast 破坏 protected 成员访问检查吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54700439/

相关文章:

c++ - 为什么 Visual Studio 2012 不为我插入括号?

c - C是否检查指针是否越界而不取消引用指针?

java - 明确指定通配符的上限时有区别吗?

c - `printf("%.-1s\n", "foo")` 会调用未定义的行为吗?

c++ - 如何计算我的程序运行需要多少毫秒?

c++ - 何时以及如何允许转换为 char 指针?

c++ - while 循环比 for 循环更有效。可能是什么原因?

c++ - 在括号内的 lambda 中声明名称为 `this` 的变量会在 3 个不同的编译器上产生不同的结果

c++ - C++ 标准在哪里允许指向未定义类型的指针?

c++ - 什么时候不应该使用[[carries_dependency]]?