使用 CTRP 时,是否访问访问父构造函数 UB 中的子属性?

Is accessing accessing a child attribute in the parent constructor UB when using CTRP?

本文关键字:访问 属性 UB CTRP 是否 使用 构造函数      更新时间:2023-10-16

我做了一个魔杖盒来捕捉我的问题:https://wandbox.org/permlink/qAX6SL43BvERo32Z

基本上,正如所暗示的那样。我正在使用 CRTP,我的基/父类构造函数使用 CTRP 中的标准方式调用子方法。

但是该子方法使用它自己的子类的属性,如果属于某种类型,例如 std::string,则似乎会导致运行时问题(例如 MSVC 上的错误分配和 GCC 上的"what((: basic_string::_M_create"/空字符串(。

长话短说,这是UB吗?如果是这样,究竟是为什么?

任何可以就如何解决这个问题提出建议的人都可以获得奖励积分。我应该/是否可以添加一个父类调用来初始化子变量的"初始化"虚拟"CTRP 方法?我是否应该通常避免在构造函数中调用 CTRP 子方法?

正在

访问父构造函数 UB 中的子属性

是的,一般来说。

。使用 CTRP 时?

是的,特别是。

如果是这样,究竟是为什么?

因为访问对象在其生存期之外的行为是未定义的。派生对象及其成员的生存期在构造 base-sub 对象时尚未开始。

结论:CRTP 基不能在其构造函数或析构函数中做 CRTP 魔术(即你不做static_cast<Derived*>(this)或类似的事情((并且要小心调用成员函数,因为这些函数也不能做同样的事情(。

任何可以就如何解决这个问题提出建议的人都可以获得奖励积分。我应该/是否可以添加一个父类调用来初始化子变量的"初始化"虚拟"CTRP 方法?

无论是否使用 CRTP,派生类构造函数都应初始化自己的变量。构造函数除了初始化对象的状态外,不应执行任何额外的操作。它不应该"做水果的事情"。