Mat*_*son 5 c++ move-semantics c++11
如果一个类没有默认的构造函数,因为它应该总是初始化它的内部变量,那么它是否应该没有一个移动构造函数?
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_;
};
Run Code Online (Sandbox Code Playgroud)
此类始终要求内部字符串由非空字符串设置,并且内部字符串在Example对象之间复制.我是否认为移动构造函数不适用于此处,因为如果移动了一个示例,则必须通过std::move调用将字符串留空?
如果一个类没有默认的构造函数,因为它应该总是初始化它的内部变量,那么它是否应该没有一个移动构造函数?
不,我不会这么说.
从一个Example对象移动并留下一个空字符串的事实在这里应该不是问题,因为通常客户不应该对移动对象的状态做出任何假设,除了它是合法的事实.
这意味着,客户端只能调用对其Example输入状态没有前提条件的函数.请注意,通常几乎所有的成员函数Example都会对对象的状态有前提条件(即string_必须是非空字符串),但不完全是所有成员函数.
例如,析构函数不Example应该介意是否string_为空 - 为什么即使在这种情况下它也不会被允许完成它的工作呢?赋值运算符是另一个常见示例 - 为什么不允许将新字符串分配给string_?.
在这个视图下,保留一个Example空字符串的对象是可以的,因为所有客户端都可以使用移动对象进行操作,基本上是重新分配它或者销毁它 - 对于这些用例,无论是否string_为空都无关紧要.
因此,拥有移动构造函数和移动赋值运算符确实有意义.