【发布时间】:2019-04-16 22:59:52
【问题描述】:
我试图理解移动语义正在寻找编译器生成的移动构造函数(复制和赋值)。
在Modern Effective C++中,Scott Meyers 在 Item #17 中说,如果没有显式声明复制构造函数,编译器将生成移动构造函数,它将为 non-static 成员执行成员移动。
为了确认这一点,我正在尝试以下代码:
#include <iostream>
#include <string>
using namespace std;
class A
{
private:
std::string str;
public:
A() : str("Init string")
{
cout << "Default constructor" << endl;
}
A(std::string _str) : str(_str)
{
cout << "Constructor with string" << endl;
}
std::string getString()
{
return str;
}
};
int main() {
A obj1;
A obj2("Obj2 string");
cout << endl;
cout << "obj1: " << obj1.getString() << endl;
cout << "obj2: " << obj2.getString() << endl;
obj1 = std::move(obj2);
cout << endl;
cout << "obj1: " << obj1.getString() << endl;
cout << "obj2: " << obj2.getString() << endl;
return 0;
}
输出是:
Default constructor
Constructor with string
obj1: Init string
obj2: Obj2 string
obj1: Obj2 string
obj2: Obj2 string
但我希望它是:
Default constructor
Constructor with string
obj1: Init string
obj2: Obj2 string
obj1: Obj2 string
obj2:
因为 obj2.str 会被移动,现在有一个空字符串。
编译器没有生成移动赋值构造函数并调用复制赋值运算符的原因是什么?
编辑: 如下实现移动赋值运算符给出了预期的输出(即调用 std::move 后的空字符串)
A& operator=(A&& obj)
{
cout << "Move assignment operator" << endl;
str = std::move(obj.str);
return *this;
}
【问题讨论】:
-
请注意,2010 年代中期的 MSVC 版本并没有在应该生成移动构造函数时生成
-
用长字符串(比如 40 个字符)再做一次测试
标签: c++ c++11 move-semantics