gpt4 book ai didi

c++ - 何时在 C++11 中使类型不可 move ?

转载 作者:IT老高 更新时间:2023-10-28 11:34:46 27 4
gpt4 key购买 nike

我很惊讶这没有出现在我的搜索结果中,考虑到 C++11 中 move 语义的有用性,我想有人会问过这个问题:

我什么时候必须(或者对我来说是个好主意)在 C++11 中使一个类不可 move ?

(原因其他不是与现有代码的兼容性问题。)

最佳答案

Herb 的回答(在编辑之前)实际上给出了一个不应该可 move 的类型的好例子:std::mutex .

操作系统的 native 互斥体类型(例如 POSIX 平台上的 pthread_mutex_t)可能不是“位置不变的”,这意味着对象的地址是其值的一部分。例如,操作系统可能会保留一个指向所有已初始化互斥对象的指针列表。如果 std::mutex包含 native 操作系统互斥体类型作为数据成员,并且 native 类型的地址必须保持固定(因为操作系统维护指向其互斥体的指针列表)然后是 std::mutex必须将 native 互斥类型存储在堆上,以便在 std::mutex 之间 move 时保持在同一位置对象或 std::mutex不得 move 。不可能将它存储在堆上,因为 std::mutex有一个 constexpr构造函数并且必须有资格进行常量初始化(即静态初始化),以便全局 std::mutex保证在程序开始执行之前就已经构造好了,所以它的构造函数不能使用new .所以剩下的唯一选择是std::mutex不动。

同样的推理也适用于其他需要固定地址的类型。如果资源的地址必须保持固定,请不要 move 它!

不 move 还有另一个论据 std::mutex也就是说,很难安全地做到这一点,因为您需要知道在互斥体被 move 的那一刻没有人试图锁定它。由于互斥锁是您可以用来防止数据竞争的构建 block 之一,如果它们本身不能安全地对抗竞争,那将是不幸的!用不动的std::mutex你知道一旦它被构建并且在它被销毁之前任何人都可以对它做的唯一事情就是锁定它并解锁它,并且这些操作被明确保证是线程安全的并且不会引入数据竞争。同样的论点适用于 std::atomic<T>对象:除非它们可以原子地 move ,否则不可能安全地 move 它们,另一个线程可能正在尝试调用 compare_exchange_strong在物体被 move 的那一刻。因此,类型不应该是可 move 的另一种情况是它们是安全并发代码的低级构建 block ,并且必须确保对它们的所有操作的原子性。如果对象值可能随时 move 到新对象,您需要使用原子变量来保护每个原子变量,以便您知道使用它是否安全或已被 move ......以及要保护的原子变量那个原子变量,等等……

我想我可以概括地说,当一个对象只是一 block 纯内存,而不是充当值的持有者或值的抽象的类型时, move 它是没有意义的。基本类型,例如 int不能 move : move 它们只是一个拷贝。你不能把 int 的内脏撕掉。 ,您可以复制它的值,然后将其设置为零,但它仍然是 int有一个值,它只是内存字节。但是一个 int在语言术语中仍然是可 move 的,因为拷贝是有效的 move 操作。然而,对于不可复制的类型,如果您不想或不能 move 这 block 内存并且您也不能复制它的值,那么它就是不可 move 的。互斥体或原子变量是内存的特定位置(使用特殊属性处理),因此 move 没有意义,也不可复制,因此不可 move 。

关于c++ - 何时在 C++11 中使类型不可 move ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14302834/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com