将指向派生类的成员变量指针转换为指向基类的成员变量是否合法?

时间:2017-09-13 02:20:16

标签: c++ language-lawyer

只要用于访问指向成员指针的指针的类型正确,以下是否会导致未定义的行为?

如果是这样,为什么我需要演员?没有它会看起来好多了(是的,我知道这只是意见问题)。

struct base {
    int foo(int base::* ptr) {
        return this->*ptr;
    }
};

struct sub : base {
    int blah{ 42 };
};

int main() {
    return sub{}.foo(static_cast<int base::*>(&sub::blah));
}

1 个答案:

答案 0 :(得分:6)

  

只要用于访问指向成员指针的指针的类型正确,以下是否会导致未定义的行为?

不,它形成得很好。来自[expr.mptr.oper]的规则是:

  

如果E1的动态类型不包含E2引用的成员,则行为未定义。

*this的{​​{3}}是sub,其中包含该成员,所以这很好。

  

如果是这样,为什么我需要演员?

因为它本身就是不安全的演员,而经验法则是本质上不安全的操作应该响亮且可见。在这种特殊情况下,它很好,但这只是因为你很小心。要求施法迫使你必须考虑它。

一个更简单的例子可能只是查看指针而不是指向成员的指针。在简单的层次结构中(假设是公共的,非模糊的等),将Derived*转换为Base*始终是安全的。那里没什么问题,所以你不需要写剧组。但是,将Base*投射到Derived*并不总是安全的......您可能没有Derived*。但是,它并非从不安全 - 完全不允许施放会很糟糕。所以安全演员是隐含的,但不安全演员必须是明确的。