为什么 std::memmove 中联合的默认非平凡移动构造函数C++?

Why is the default nont-trivial move constructor of unions in C++ std::memmove?

本文关键字:移动 C++ 构造函数 memmove std 为什么 默认      更新时间:2023-10-16

假设联合拥有一个具有非平凡移动构造函数的类类型,如std::shared_ptr(或std::string?现在使用std::move将此联合移动到另一个联合。当源对象超出范围时,它将被销毁,对吗?但是,如果在移动时未将其设置为"empy"状态,则可能会释放其析构函数中实际上应属于新位置的资源。这种行为不是很危险吗?- 特别是因为类/结构类型的默认非平凡移动构造函数是不同的,因为它执行成员级移动,允许成员清理源对象。

一个union类型,它包含一个成员,其移动构造函数是非平凡的,将有一个已删除的隐式移动构造函数。此外,尝试= default移动构造函数也会将其删除。实质上,此类类型不可能有有效的移动默认行为。

因此,如果我们有一个union,它有一个具有非平凡移动构造器的成员,并且您可以合法地移动构造一个,那么该union必须有一个用户定义的移动构造函数。因此,用户有责任确保移动构造函数为当前活动成员执行正确的操作。

移动构造函数或移动赋值运算符需要使移动对象处于未知(除非记录(、有效和可破坏的状态。如果不这样做,那么移动构造函数/运算符就会被破坏。

如果您从对象移动并且它的移动构造函数使 moved-from 对象处于删除它会导致资源或类似资源双重删除的状态,那么实现移动构造函数/运算符的人都没有正确完成这项工作。