我正在测试移动构造函数并执行以下操作:
#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;
}
我在输出中的预期是在评论中,但是在编译时(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";
}
然后
X a(10, "a"); //constructor
X b(a); // copy
X c(X(3, "pom")); //constructor, move
我得到了预期的结果......我真的不明白为什么。
编辑:现在在GCC 4.7.2上进行了测试,在两种情况下都没有调用Move构造函数,但C ++ Builder XE5编译器在两种情况下都调用了Move构造函数。然而,VS仅在第二种情况下调用它(当使用额外的构造函数参数时)。很有意思......
答案 0 :(得分:7)
编译器正在忽略移动构造并将X(3)
直接构建到c
,实质上将初始化转换为
X c(3);
使用gcc,您可以使用-fno-elide-constructors
开关禁用此功能。添加后,原始示例的输出符合预期:
Constructor
Copy
Constructor
Move