- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
让我们看看一些简单的可 move 构造和(不是简单的)可复制构造(但仍然可复制构造)的用户定义(类)类型 A
:
struct A
{
A() = default;
A(A const &) {}
A(A &&) = default;
};
然后 A
的 move ( move 构造或 move 赋值)从字面上执行以下操作:将源按位复制到目标,尽管操作名称为“move ” .在平凡的 move 中,右手边(正式地)不是 const
,但是整个操作的平凡性要求右手边(实际)不可改变,不是吗?在我看来,这意味着平凡的复制操作和平凡的 move 操作在它们的深层本质上完全相同(在内存、内存布局、位等方面)。我说得对吗?
如果是这样,那么我想,如果我在用户代码中看到平凡的 move 构造类型,而不是平凡的复制构造类型,那么我显然看到了一些反模式。我说得对吗?
是否有这样一个人造但可用的类型的例子,它不是平凡的复制构造/可分配的,而是平凡的 move 构造/可分配的?
最佳答案
是否存在一个类型可以有一个普通的复制构造函数而没有一个普通的 move 构造函数的用例?当然。
例如,拥有一个在 move 时始终为空的指针包装类型可能很有用。复制构造函数没有理由不重要,但 move 构造函数必须将旧值设置为 NULL。
template<typename T>
class empty_on_move
{
T *ptr_;
public:
empty_on_move(const empty_on_move&) = default;
empty_on_move(empty_on_move &&other) : ptr_(other.ptr_) {other.ptr_ = nullptr;}
...
};
empty_on_move
不拥有该对象,这就是为什么可以拥有它的多个拷贝的原因。它的存在只是为了确保当您离开它时,指针处于易于理解的状态。因此,is_trivially_copy_constructible<empty_on_move<T>>
是真的,而is_trivially_move_constructible<empty_on_move<T>>
是假的。
它主要用于其他想要提供特定行为指针的类内部。这样,您就不必显式地将代码写入它们的 move 构造函数/赋值中,以将这些字段清零。
话虽这么说,你真的问错了问题。为什么?因为答案并不重要。
复制/move 构造函数/赋值的琐碎性唯一重要的是当您需要类型为 Trivially Copyable 时. 那个属性允许使用memcpy
诸如此类的事情,不是个别操作的琐碎。平凡可复制属性要求复制/move 构造函数/赋值和析构函数所有都是平凡的(在 C++14 中,要求它们可以是平凡的或删除的,但至少有一个必须是非平凡的-删除)。
如果您正在围绕某种类型编写包装器(或编写求和/乘积类型),并且您想要公开该类型的属性,您只需要关心公开平凡可复制性。也就是说,如果 T
(或 Ts...
)是平凡可复制的,那么你的类型也应该是平凡可复制的。
但除此之外,你不应该仅仅因为 T
就觉得需要一个简单的复制构造函数。
关于c++ - 琐碎的复制和 move 操作是否不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39611510/
我认为这相对简单,但我很困惑,因为我是类图的新手。 我将要创建一个程序(用 Java)来管理麦当劳的员工类型。因此,考虑为对象建模。 为了简单起见,麦当劳只有两种员工,“主管”和“船员”,两者都是按月
我有一个很小的 Android 项目,是我拼凑而成的,用于了解 Android 单元和仪器测试。我使用dog.ceo API 来获取狗的随机图像。程序本身按其应有的方式运行。但是,每当我运行或调试
我是一名优秀的程序员,十分优秀!