Tra*_*cer 0 c++ constructor move-semantics c++11
我正在测试一个移动构造函数并执行以下操作:
#include <iostream>
#include <string>
using namespace std;
class X{
public:
int* p;
int size;
X(){}
X(int n) : size(n){
p = new int[n];
for(int i = 0; i < n; i++)
p[i] = i;
cout << "Constructor\n";
}
~X(){
delete[] p;
}
X(const X& r){
cout << "Copy\n";
}
X(X&& r){
p = r.p;
size = r.size;
r.p = NULL;
r.size = 0;
cout << "Move\n";
}
};
int main() {
X a(10); //constructor
X b(a); // copy
X c(X(3)); //constructor, move
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在输出中的预期是在注释中,但是在编译时(VS 2012)移动构造函数没有被调用?!但是,如果我向构造函数添加其他参数:
string name;
X(int n, string _name) : size(n), name(_name){
p = new int[n];
for(int i = 0; i < n; i++)
p[i] = i;
cout << "Constructor\n";
}
Run Code Online (Sandbox Code Playgroud)
然后
X a(10, "a"); //constructor
X b(a); // copy
X c(X(3, "pom")); //constructor, move
Run Code Online (Sandbox Code Playgroud)
我得到了预期的结果......我真的不明白为什么.
编辑:现在在GCC 4.7.2上测试,它在两种情况下都不调用Move构造函数,但C++ Builder XE5编译器调用两种情况下的Move构造函数.然而,VS仅在第二种情况下调用它(当使用额外的构造函数参数时).很有意思...
编译器eliding移动建设并直接构建X(3)成c,基本上是把你的初始化成
X c(3);
Run Code Online (Sandbox Code Playgroud)
使用gcc,您可以使用-fno-elide-constructors开关禁用它.添加后,原始示例的输出符合预期:
Constructor
Copy
Constructor
Move
Run Code Online (Sandbox Code Playgroud)