移动构造函数的问题

时间:2014-07-11 13:19:10

标签: c++ c++11 constructor move-semantics

我正在测试移动构造函数并执行以下操作:

#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仅在第二种情况下调用它(当使用额外的构造函数参数时)。很有意思......

1 个答案:

答案 0 :(得分:7)

编译器正在忽略移动构造并将X(3)直接构建到c,实质上将初始化转换为

X c(3);

使用gcc,您可以使用-fno-elide-constructors开关禁用此功能。添加后,原始示例的输出符合预期:

Constructor
Copy
Constructor
Move

Live demo