【问题标题】:Why is the downcast in CRTP defined behaviour为什么 CRTP 定义行为中的沮丧
【发布时间】:2019-07-12 11:39:55
【问题描述】:

我使用 CRTP 模式已经有一段时间了,但是阅读有关与向下转换相关的未定义行为的答案我不明白为什么 static_cast<Derived&>(this),其中 this 的类型为 Base<Derived>* 是定义的行为,其中 @987654327 @ 公开继承自 Base<Derived>

标准很明确:

static_cast (表达式)

如果 new_type 是指向某个类 D 的指针或引用,并且表达式的类型是指向其非虚拟基 B 的指针或引用,则 static_cast 执行向下转换。如果 B 是模棱两可的、不可访问的或 D 的虚基(或虚基的基),则这种向下转换是病态的。

但是看着类似的问题,C++ inheritance downcasting

如何从点对象 [基类] 转换为子点对象 [派生类]?

评分最高的答案:

"你不能;除非点 [Base] 有一个转换运算符,或者子点 [Derived] 有一个转换构造函数,在这种情况下对象类型无需演员即可转换。”

另一个例子:static_cast parent class to child class C++

// B : public A
A a;
B* bptr = static_cast<B*>(&a);

评分最高的评论:

“这是未定义的行为。”

然后说:

“您可以使用 CRTP 或 dynamic_cast 安全地做到这一点。”

这里 (C++ static_cast downcast validity) 再次提到:

Base base{190};
A& a = static_cast<A&>(base);

“不[无效],Base类型的对象不是A类型的对象[Derived]”


在 CRTP 中进行向下转换有何不同;为什么它不会导致未定义的行为,但上述情况会导致?按照上面答案的逻辑,说Base&lt;Derived&gt; 不是Derived 类型的对象不是真的吗(反之亦然),但你可以使用static_cast

也许我只是误解了 CRTP。

【问题讨论】:

  • 您混淆了“对象”和“指向对象的指针”。

标签: c++ undefined-behavior crtp static-cast


【解决方案1】:

重温第一段:

如果 new_type 是指向某个类 D 的指针或引用,并且表达式的类型是指向其非虚拟基 B 的指针或引用,则 static_cast 执行向下转换。如果 B 是模棱两可的、不可访问的或 D 的虚基(或虚基的基),则这种向下转换是病态的。

包括下一句:

此类 static_cast 不进行运行时检查以确保对象的运行时类型实际上是 D,并且只有在通过其他方式(例如实现静态多态性时)保证此前提条件时才能安全使用。

CRTP 使用/是静态多态性的另一个名称。

给定struct D : B&lt;D&gt; 如果B&lt;D&gt; static_cast*thisD&amp;,那么这是定义的行为,因为this 指针实际上是指向DB&lt;D&gt; 的指针.

【讨论】:

    猜你喜欢
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多