2016-07-06 18 views
2

をコンストラクタを呼び出さずにオブジェクトのインスタンス化。は、私はC++での新たなんだと私は現在、コンストラクタについて学んだC++で

1- Dog dog; 
2- Dog dog = Dog(); 
3- Dog *dog = new Dog; 
4- Dog *dog = new Dog(); 
5- Dog dog(); 

class Dog{ 
    Dog(){ 
     std::cout << "Constructor called! 
    } 
}; 

は、私は(私は間違っていない場合)、我々は、例えば、オブジェクトを作成することができますC++では異なる方法があることを知っている:私はコンストラクタを持つクラスの犬を持っていると言いますしかしここには事があります:1から4までのステートメントはすべてコンストラクタを呼び出しますが、ステートメント番号5はそうではありません。理由を理解することができます。

あなたは第五文は、クラスのコンストラクタを呼び出すことはありません、なぜ任意のアイデアを持っていますか?おかげさまで

+4

5は、関数のプロトタイプで、最も厄介な解析を参照してください。 – sergej

+0

5はDogオブジェクトを作成しません。 – sergej

+2

@sergej答えとしてコメントを追加する必要があります。あまりにも遅い。 HolyBlackCatはあなたにそれを打つ。 –

答えて

5

5は、C++のmost vexing parseの例です。

Dog dog(); 

これはパラメータを受け入れないとDogを返すdogという名前の関数を宣言します。 (あなたがC++ 11を使用している場合と)最も厄介な解析を避けるために、あなたが行うことができます:意味的に

Dog dog{}; 

とを(C++ 17には、少なくともまで)、Dog dog = Dog();は最初の一時オブジェクトを作成します。その後、(Dog())、および(Dogクラスは何の動きコンストラクタを持っていない場合は、構築またはコピー)、それから、指定されたオブジェクト(dog)を構築移動します。コンパイラは移動を最適化することができますが、このステートメントは他のセマンティクスとは異なります。

私の記憶が正しければ、それはDog dog;と同じ意味を持つように、C++ 17以降、P0135r0Dog dog = Dog();のセマンティクスを変更します。

EDIT:としてはコメントで@LightnessRacesinOrbitが指摘し、Dog dog();はかなり最も厄介な解析厄介ですが、ありません。 Dog dog(Dog());が真実です。 Dog dog();はちょうど良い、平凡な宣言であると思います。

+0

@LightnessRacesinOrbitうーん、私は間違っている可能性があります。 *関数宣言として解析できるものはどれも* - この最も厄介な構文解析ではありませんか? –

+1

いいえ、それは言語の単純な事実です。最も厄介な構文解析( 'Dog Dog(Dog) ')につながっていますが、これはあまり意味がありません。私はそれを妥協として「より厄介な構文解析」と呼んでいます;) –

2
Dog dog(); 

この行はオブジェクトを作成せず、関数宣言として解析されます。

私が正しく覚えていれば、という最も厄介な構文解析と呼ばれています。

関連する問題