2014-07-11 69 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:點亮。 –