0Pricing
C++ Academy · 课时

移动构造函数与移动赋值

正确实现移动构造函数和移动赋值运算符

移动构造函数与移动赋值 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

两个特殊成员

移动构造函数和移动赋值运算符让您的类可以取得另一个实例的资源所有权,而无需复制。

签名

两者都接受对同一类型的右值引用。

class String {
public:
    String(String&& other) noexcept;          // move ctor
    String& operator=(String&& other) noexcept; // move assign
};

实现移动构造函数

窃取源对象的资源,并让源对象处于有效的空状态。

String(String&& other) noexcept
    : data_(other.data_), size_(other.size_) {
    other.data_ = nullptr;
    other.size_ = 0;
}

实现移动赋值

分三步:释放当前资源,窃取源对象的资源,让源对象为空。

String& operator=(String&& other) noexcept {
    if (this != &other) {
        delete[] data_;
        data_ = other.data_;
        size_ = other.size_;
        other.data_ = nullptr;
        other.size_ = 0;
    }
    return *this;
}

为什么 noexcept 很重要

请尽可能将移动操作标记为 noexcept。像 std::vector 这样的标准容器只有在移动操作为 noexcept 时,才会在调整大小时使用移动;否则,为了保证异常安全,它们会退回使用复制。

五法则

如果您编写了以下五者中的任何一个,就应考虑全部五者:

  • 析构函数
  • 复制构造函数
  • 复制赋值运算符
  • 移动构造函数
  • 移动赋值运算符

零法则

更好的做法是一个也不编写。将成员存储为 RAII 类型(向量、字符串、智能指针)。编译器生成的默认实现可以正确且高效地工作。

class Widget {
    std::string name_;
    std::vector<int> data_;
    // No need for destructor, copy, or move — compiler does the right thing
};

编译器生成移动操作的条件

编译器仅在满足以下条件时生成默认移动成员函数:

  • 没有用户声明的复制构造函数、复制赋值运算符、析构函数或移动成员函数
  • 所有成员和基类本身都支持移动

默认化与删除的移动操作

您可以显式请求或禁止编译器生成移动操作。

class Widget {
public:
    Widget(Widget&&) = default;
    Widget& operator=(Widget&&) = default;
    // or
    Widget(Widget&&) = delete;
};

移动操作之后

被移动对象处于有效但未指定的状态。您可以:

  • 销毁它
  • 为它赋予新值
  • 调用任何没有前置条件的操作(size()、empty()、clear())

应用场景

移动语义可以加快以下操作:

  • 返回大型对象(RVO 未生效时)
  • 将大型对象放入容器(对右值调用 push_back)
  • 实现您自己的资源所有权类型

快速检查

为什么应该将移动构造函数和移动赋值运算符标记为 noexcept?

总结

移动构造函数和移动赋值运算符会从即将销毁的右值中接管资源。将它们标记为 noexcept 可以提升容器的速度。请遵循五法则;更理想的是通过组合标准 RAII 类型来遵循零法则。

常见问题解答

「移动构造函数与移动赋值」课时是免费的吗?

是的 — 「移动构造函数与移动赋值」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「移动构造函数与移动赋值」这节课中我会学到什么?

正确实现移动构造函数和移动赋值运算符 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「移动构造函数与移动赋值」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 左值与右值:区别所在
  2. 右值引用与 && 语法
  3. std::move 与 std::forward
  4. 移动构造函数与移动赋值
← 返回 C++ Academy