03 November 2022

C++ 核心指南目录

“Make move operations noexcept”

理由

移动操作过程中抛出异常,有违大多数人的常理。在标准库和语言工具中使用时,一个不抛出异常的移动操作效率更高。

例子

template<typename T>
class Vector {
  public:
    Vector(Vector&& a) noexcept
        :elem{a.elem}, sz{a.sz}
        {
            a.sz = 0; a.elem = nullptr;
        }
    Vector& operator=(Vector&& a) noexcept
        {
            elem = a.elem; sz = a.sz; a.sz = 0; a.elem = nullptr;
        }
    // ...
private:
    T* elem;
    int sz;
};

坏例子

template<typename T>
class Vector2 {
public:
    Vector2(Vector2&& a) { *this = a; }             // just use the copy
    Vector2& operator=(Vector2&& a) { *this = a; }  // just use the copy
    // ...
private:
    T* elem;
    int sz;
};

Vector2 不仅效率不高,而且因为 vector 的复制/拷贝操作需要分配内存,会抛出异常。

强化

  • (简单)移动操作应该标记为 noexcept