【发布时间】:2017-05-20 16:44:24
【问题描述】:
我创建了一个基本的测试类来了解移动构造函数的工作原理。移动构造函数似乎没有被调用,我不确定实际调用了什么构造函数。如果我使用 std::move 则调用移动构造函数,但常规 R 值实际上不会调用它。为什么会发生这种情况,实际调用的是什么构造函数?我正在使用 g++ 4.6.3
#include <iostream>
#include <cstring>
class Test
{
int a;
int b;
int* c;
public:
Test(int one, int two)
{
std::cout << "Param Constructor" << "\n";
a = one;
b = two;
}
Test()
{
std::cout << "Default Constructor" << "\n";
a = 1;
b = 2;
}
~Test()
{
std::cout << "Deconstructor" << "\n";
}
Test(const Test& test)
{
a = test.a;
b = test.b;
std::cout << "Copy constructor called" << "\n";
}
Test(Test&& test)
{
std::cout << "Move constructor called" << "\n";
a = test.a;
b = test.b;
}
Test& operator=(const Test& test)
{
std::cout << "in operator=" << "\n";
a = test.a;
b = test.b;
return *this;
}
};
Test createTest()
{
return Test(1,2);
}
int main()
{
Test test(createTest());
Test test2 = test;
std::cout << "After logic" << "\n";
return 0;
}
我得到的输出:
Param Constructor
Copy constructor called
After logic
Deconstructor
Deconstructor
我创建了一个名为 test 的类型为 Test 的对象,但没有创建它的输出?我期待这个输出:
Param Constructor
Move Constructor // (Missing)
Deconstructor //Deleting instance from createTest (Missing)
Copy constructor called
After logic
Deconstructor
Deconstructor
【问题讨论】:
-
复制省略。使用
-fno-elide-constructors编译。 -
这实际上说明了一个非常棒的观点:调用
std::move在某些情况下实际上可能是有害的。特别是,在函数内部的 return 语句的值上调用它,或者在调用范围内的函数调用返回时调用它。无论如何,这两个东西都已经是右值,所以没有任何好处。但正如您所见证的,它实际上可以防止复制省略。移动构造函数可能比复制构造函数更好,但是 no 构造函数调用是最快的:-)