c++ - 没有默认构造函数会导致没有 move 构造函数吗?

标签 c++ c++11 move-semantics

如果一个类没有默认构造函数,因为它应该始终初始化它的内部变量,那么它不应该有一个 move 构造函数吗?

class Example final {
public:
  explicit Example(const std::string& string) : string_(
    string.empty() ? throw std::invalid_argument("string is empty") : string) {}
  Example(const Example& other) : string_(other.string_) {}
private:
  Example() = delete;
  Example(Example&& other) = delete;
  Example& operator=(const Example& rhs) = delete;
  Example& operator=(Example&& rhs) = delete;
  const std::string string_;
};

此类始终期望内部字符串由非空字符串设置,并且内部字符串在 Example 对象之间复制。 move 构造函数不适用于此处是否正确,因为如果 move 了 Example,则必须通过 std::move 调用将字符串留空?

最佳答案

If a class doesn't have a default constructor as it should always initialize it's internal variables, would it follow that it shouldn't have a move constructor?

不,我不会这么说

Example 对象 move 并留下空字符串的事实在这里应该不是问题,因为通常客户端不应该对 move 对象的状态做出任何假设, 除了它是合法的。

这意味着,客户端只能调用对其 Example 输入的状态没有前置条件的函数。请注意,通常 几乎所有 Example 的成员函数都会有对象状态的前提条件(即 string_ 必须是一个非空字符串),但不是全部

例如,Example 的析构函数不应该介意 string_ 是否为空 - 为什么即使在这种情况下也不允许它完成它的工作?赋值运算符是另一个常见示例 - 为什么不允许将新字符串分配给 string_

在这种观点下,将 Example 对象保留为空字符串是可以的,因为客户对移出的对象所能做的基本上就是重新分配它或销毁它 - 并且对于在这些用例中,string_ 是否为空应该无关紧要。

因此,拥有 move 构造函数和 move 赋值运算符确实有意义

关于c++ - 没有默认构造函数会导致没有 move 构造函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16019601/

相关文章:

c++ - 关于两个类的范围的错误

c++11 - 完美转发 - 这是怎么回事?

class - C++ 从不同类访问一个类中函数中的变量

c++ - 为什么我们保留互斥量而不是每次都在守卫之前声明它?

c++ - vector 中的不可复制元素

c++ - 使用已被 std::move 到别处的变量时出现错误,或至少出现警告

c++ - move 初始化列表的元素是否安全?

c++ - 函数参数没有类型

c++ - 在堆栈上创建 QLayout 是否安全?

c++ - 如何使用 OpenCL 构建 ImageMagick?