2012-03-14 17 views
-1

は、私はいくつかのサイトから調査対象とVisual Studio 11 Expressのベータ版を使ってみました。..以下移動コンストラクタと非constコピーコンストラクタ

は私のテストコードです...

#include <iostream> 

using namespace std; 

class Foo 
{ 
public: 
    Foo() 
     : Memory(nullptr) 
    { 
     cout<<"Foo Constructor"<<endl; 
    } 
    ~Foo() 
    { 
     cout<<"~Foo Destructor"<<endl; 
     if(Memory != nullptr) 
      delete []Memory; 
    } 
    Foo(Foo& rhs) 
     : Memory(nullptr) 
    { 
     cout<<"Copy Constructor"<<endl; 

     //allocate 
     //this->Memory = new .... 
     //copy 
     //memcpy(this->Memory, rhs.Memory...); 
    } 

    Foo& operator=(Foo& rhs) 
    { 
     cout<<"="<<endl; 
    } 
    void* Memory; 

    Foo(int nBytes) { Memory = new char[nBytes]; } 

    Foo(Foo&& rhs) 
    { 
     cout<<"Foo Move Constructor"<<endl; 
     Memory = rhs.Memory; 
     rhs.Memory = nullptr; 
    } 
}; 

Foo Get() 
{ 
    Foo f; 
    return f; 
    //return Foo(); 
} 
void Set(Foo rhs) 
{ 
    Foo obj(rhs); 
} 
int main() 
{ 
    Set(Get()); 
    return 0; 
} 

移動コンストラクタが入力されない理由はわかりません。

これは本当にGet()のRvalueです。

私はconstのコンストラクタから非constコピーコンストラクタを変更した場合、

それはコンストラクタを動かす入ります。行動が変わった...

なぜそれが起こったのかを親切に説明できますか?

+5

'delete [] void_ptr;'は未定義の動作です。 'delete nullptr'は完全にうまくいくので、事前に確認する必要はありません。また、不要な定型コードをすべて必要としません。それをカットして、きれいな例を質問に貼り付けてください。 http://sscce.orgを読んでください。 – Xeo

+0

ああ、質問への答え:あなたは(コンパイラよりも)(http://ideone.com/wzeKF)である可能性が非常に高いです( 'g'の中に行方不明のコピーがあることに注意してください。 。最適化を有効にすると、コンパイラはすべての移動/コピーを消去します。 – Xeo

+0

@ Xeo:あなたの例では 'X f()'に 'return'がありません。 – Mankarse

答えて

1
#include <iostream> 

using namespace std; 

class Foo 
{ 
public: 
    Foo(): 
     Memory(nullptr) 
    { 
     cout<< this << "Foo Constructor"<<endl; 
    } 

    ~Foo() 
    { 
     cout<< this << "~Foo Destructor"<<endl; 
     if(Memory != nullptr) 
      delete []Memory; 
    } 

    Foo(Foo& rhs) 
     :Memory(nullptr) 
    { 
     cout<<this << "Copy Constructor"<<endl; 

     //allocate 
     //this->Memory = new .... 
     //copy 
     //memcpy(this->Memory, rhs.Memory...); 
    } 

    Foo& operator=(Foo& rhs) 
    { 
     cout<<"="<<endl; 
    } 
    void* Memory; 

    Foo(int nBytes) { Memory = new char[nBytes]; } 

    Foo(Foo&& rhs) 
     { 
     cout<<this << "Foo Move Constructor"<<endl; 

       Memory = rhs.Memory; 


       rhs.Memory = nullptr; 
     } 

}; 

Foo Get() 
{ 
    Foo f; 
    cout << &f << "f" <<endl; 
    return f; 
} 

void Set(Foo rhs) 
{ 
    Foo obj(rhs); 
    cout << &obj << "obj"<<endl; 
} 

int main() 
{ 
    Set(Get()); 
    return 0; 
} 

出力...

0x7fffe38fa0a0 Foo Constructor 
0x7fffe38fa0a0 f 
0x7fffe38fa070 Copy Constructor 
0x7fffe38fa070 obj 
0x7fffe38fa070 ~Foo Destructor 
0x7fffe38fa0a0 ~Foo Destructor 

回答:により名前付き戻り値の最適化にパラメータRHSは、ローカル変数fの別名としてインプレース構成されています。 (つまり、rhsとfは同じインスタンスです)。

rhsは左辺値なので、コピーコンストラクタを使用してrhsから構造体objをコピーします。

関連する問題