2014-07-11 68 views
0

我在测试一个移动的构造,也做了以下内容:与移动构造函数问题

#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,它不叫在这两种情况下,但C++ Builder中XE5编译器调用构造函数移动移动构造函数在这两种情况下。然而,VS只在第二种情况下才使用它(当使用额外的构造函数参数时)。非常有趣......

+0

尝试使用['标准:: move'(http://en.cppreference.com/w/cpp /效用/移动)。 –

+0

我知道std :: move,但是这并不能回答我的问题。 – Tracer

+0

当然不会,否则我会写回答而不是评论。 :) –

回答

7

编译器eliding移动建设和直接建设X(3)c,基本上是把你的初始化成

X c(3); 

与海湾合作委员会,你可以使用-fno-elide-constructors开关禁用此。一旦你添加,从原来的例子的输出为预期:

Constructor 
Copy 
Constructor 
Move 

Live demo

+0

+1:点亮。 –