2

以下はコンストラクタをテストするためのスニペットです。それはVS 2015で実行されました。匿名オブジェクトを使用するときにデフォルトコンストラクタもコピーコンストラクタも呼び出されません

私の意見では、 "B b(B)"は "B b = B()"と同じ機能を持ちますが、私のコードでは動作が異なると言われるようです。

コンパイラの最適化によるコピーエリジョンがあることは知っていますが、少なくとも "B(B())"を実行するときは、デフォルトのコンストラクタを呼び出す必要があります。 誰かが私の誤解がどこにあるのかを指摘できますか?

class B 
{ 
public: 
    B() { 
     ++i; 
     x = new int[100]; 
     cout << "default constructor!"<<" "<<i << endl; 
     cout << "x address:" << x << endl << "--------" << endl; 
    } 
    B(const B &b) //copy constructor 
    { 
     ++i; 
     cout << "Copy constructor & called " << i<< endl 
      << "--------" << endl; 
    } 
    B(B &&b)//move constructor 
    { 
     x = b.x;  
     ++i; 
     b.x = nullptr; 
     cout << "Copy constructor && called" << i << endl 
      <<"x address:"<< x << endl << "--------" << endl; 

    } 
    void print() 
    { 
     cout << "b address:" << x << endl << "--------" << endl; 
    } 
private: 
    static int i; 
    int *x; 
}; 
int B::i = 0; 


int main() 
{ 
    B b1; //default constructor 
    b1.print(); 
    B b2 = B(); //default constructor only 
    b2.print(); 
    B b3(B()); //????nothing called... why??? 
    B b4 = b2; //copy constructor 
    B b5 = move(b2); //move constructor 
    b2.print(); 

    return 0; 
} 

enter image description here

答えて

4

B b(B())次に、コンストラクタが呼び出されないであろう、関数宣言、全く変数の定義であることに留意されたいです。 Most vexing parseによれば

B b(B())Bのオブジェクトを戻し、タイプBを返すと全くパラメータを取るない関数へのポインタである単一の(名前)パラメータを有するb命名関数の関数宣言、です。

あなたは

B b1(B{}); 
B b2{ B() }; 
B b3{ B{} }; // preferable from C++11 
+0

のようなナイスキャッチ、中括弧(list initlization()11 C++以降)を使用して、それを解決することができます! @ Shirley Feng、wikiの記事によると、内部のctor呼び出しの周りに括弧を追加することで、予想される動作を得ることができます。例: 'B b3((B()));' – souldzin

+0

共有いただきありがとうございます!それは私を助けるXD –

+0

ちょうど、初期化のために1つの規則を使い続けるほうがよいのではないでしょうか?つまり、 'B b {} {;}の代わりに –

関連する問題