移动语义是否只是一个浅层副本并将其他人的指针设置为 null?
Is move semantics just a shallow copy and setting other's pointers to null?
我一直在阅读C++中的移动语义,在解释中,人们给出了很多类比来帮助简化它,在我的脑海中,我所能看到的是,人们所说的"移动"而不是"复制"只是对象的浅层副本,并将"从"对象中的任何指针设置为null。这基本上就是要点吗?浅拷贝并将其他指针设置为null?
浅拷贝并将其他指针设置为null?
浅拷贝-是。将他人的指针设置为null-并不总是。
最低要求是移动的from对象处于"未定义但有效的状态",也就是说,您可以重新分配给它,再次移动它或删除它,而不会导致程序失败,但不会对它执行其他依赖于状态的操作。这意味着,根据std::swap
实现移动分配通常是完全有效的。
有些对象定义了更强的契约。其中之一是CCD_ 2。从其中一个移动会导致它包含null
,但这是明确记录的。
移动语义只是一个浅层复制并将其他指针设置为null吗?
如果指针为null满足类不变量,则可以是。也就是说:如果具有空指针的对象是一个有效状态。
因此,我将给出一个更长的描述:Move构造函数和赋值运算符执行一个浅层复制,并将moved-from对象清理到满足类不变量的状态。
还要记住,在移动赋值的情况下,必须记住处理将被吞咽副本覆盖的指针。
例如,如果类拥有指向对象,则不变量要求没有两个对象拥有同一对象。至少有三种方法可以实现这一点:
- 将指针设置为null
- 构造新对象
- 将指针与移动到的对象交换(在移动构造函数的情况下,这基本上与前面的一个选项相同,因为除非首先执行前面的某个选项,否则指针最初是未初始化的,但通过移动赋值,这可以方便地处理移动到对象之前指向的对象)
如果不变量需要,有时还需要设置非资源数据,如size
字段或类似数据,以匹配对象的新状态。除了拥有指向内存的指针之外,对象可能还拥有其他资源,例如文件描述符,还必须清理这些资源。
相关文章:
- 用callgrind追踪不必要的副本
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 检查注册表项是否链接到(或副本)另一个注册表项
- 为什么构建目录中新构建的共享库与安装目录中的副本具有不同的依赖项集?
- C++基于范围的 for 循环和元素副本
- 创建提升::shared_ptr的深层副本
- 如何从构造函数副本 T(const T&)调用对象 T?
- 副本初始化的默认模板参数推导
- C++深浅的副本
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- Eigen - matrix.transpose 会创建矩阵的副本吗?
- 将 MatrixXd 的行传递给要修改的函数,而不在 Eigen 中创建副本
- 对如何制作双链表的深度副本感到困惑?
- 为什么 std::string s = "123" 当不涉及副本时被视为复制初始化?
- 为什么 g++ 10.1 抱怨头文件中的命名 lambda,而其他人则没有?
- 指向基类的指针的 std::vector 的深层副本
- 如何避免将数据缓冲区的额外副本复制到字符串?
- 无法识别的类函数副本
- 移动语义是否只是一个浅层副本并将其他人的指针设置为 null?