考虑测试 1:
class MyClass
{
private:
string data;
public:
MyClass()
{
std::cout << "MyClass()" << std::endl;
}
MyClass(string data) : data(data)
{
std::cout << "MyClass(string data)"<< std::endl;
}
~MyClass() {}
MyClass(const MyClass& obj) // copy constr
{
std::cout << "MyClass(const MyClass& obj)" << std::endl;
}
MyClass(MyClass&& obj) // move constr
{
std::cout << "Move constructor. MyClass(MyClass&& obj)" << std::endl;
}
};
int main()
{
MyClass obj = move(MyClass("privet"));
cout << "-----------------------------" << endl;
MyClass ob = MyClass("hello");
return 0;
}
结论:
MyClass(string data)
Move constructor. MyClass(MyClass&& obj)
-----------------------------
MyClass(string data)
我不明白为什么MyClass ob = MyClass("hello");
只在行中调用构造函数。我期待看到一个临时对象上的构造函数调用MyClass("hello")
,然后是移动构造函数调用MyClass ob
,它将rvalue reference
给定的临时对象作为参数,就像MyClass obj = move(MyClass("privet"));
考虑测试 2:
class A
{
public:
A()
{
std::cout << "A()" << std::endl;
}
A(const A& other)
{
std::cout << "Copy ctor\n";
}
A(A&& other)
{
std::cout << "Move ctor\n";
}
};
void first(A a) {}
void second(A&& a) {}
int main()
{
first(A{});
std::cout << "Let's call the second:\n";
second(A{});
return 0;
}
结论:
A()
Let's call the second:
A()
我不明白这里如何调用构造函数。为什么每个函数只有一个,但它们必须由临时对象的构造函数调用,并且在函数的情况下,first
创建另一个本地对象 - 副本,在second
没有线索的函数的情况下
您正确理解了所有内容,但允许编译器优化这样的内容。这称为复制省略。GCC 有一个标志
-fno-elide-constructors
可以禁用此功能。由于 C++17 这种优化已经成为强制性的(保证复制省略),所以现在 even
A a = A(A(A()));
应该总是等价于A a;
.更多的:
MyClass(string data) : data(data)
应替换为MyClass(string data) : data(std::move(data))
.