【发布时间】: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<Derived> 不是Derived 类型的对象不是真的吗(反之亦然),但你可以使用static_cast?
也许我只是误解了 CRTP。
【问题讨论】:
-
您混淆了“对象”和“指向对象的指针”。
标签: c++ undefined-behavior crtp static-cast