2016-07-17 6 views
2

もう一つのC++の質問ですが、オブジェクトを構築するときに "="を使用する効果は何ですか?検討してください:"="を使用したオブジェクト構築の効果

class Foo { 
    private: 
     int bar; 
     int baz; 

    public: 
     Foo(int bar, int baz) 
      :bar(bar), baz(baz) {} 
}; 

int main() { 
    Foo foo1{4, 2}; 
    Foo foo2 = {4, 2}; 
    Foo foo3 = Foo{4, 2}; // I prefer this one for aesthetic reasons. 

    return 0; 
} 

ベストプラクティスとはどのような違いがありますか。

また、私たちはベストプラクティスについて話していますが、暗黙的な変換を伴う奇妙な動作のために、コンストラクタにexplicitを追加するのがGood Idea™だと聞きました。なぜそれが

error: chosen constructor is explicit in copy-initialization 

です:

Foo foo2 = {4, 2}; 

がエラーでコンパイルに失敗:この、突然

public: 
     explicit Foo(int bar, int baz) 
      :bar(bar), baz(baz) {} 

:だから私はFooのコンストラクタにexplicitを追加しましたか?

+1

2つの相違点:1)コピー初期化は明示的なコンストラクタでは機能しません。 2) 'auto'はコピーと直接初期化の間で' std :: initializer_list'を異なる方法で引きます。残りの部分については、C++ではそれが問題になります。 – ildjarn

+3

'Foo foo3 = Foo {4,2}; //私はこの方が好きです。なぜ私は分かりません。概念的には、完全に無意味な余分なコピーが含まれていますが、現実的には最適化コンパイラが間違いを元に戻します。しかし、それは冗長で醜いだけです。それは冗長なときに、なぜあなたがしなければならない以上のことを書いていますか?'Foo foo {4,2};は優れています。 –

+2

"コンストラクタに明示的に追加すると聞きました..." - 恐ろしく包括的であることに加えて、言及されたどこにでも言及しなかった作者は、なぜ*これが良いアイデアだと思ったのですか?あなたは同意した、同意しなかった、または単にその正当性を理解していませんか?最後に、[この明示的な説明](http://en.cppreference.com/w/cpp/language/explicit)は検討する価値があります。 – WhozCraig

答えて

8

What are the differences

Foo foo1{4, 2}; 

これはdirect initialization (2)です。

Direct initialization is performed in the following situations:

2) during list-initialization sequence, if no initializer-list constructors are provided and a matching constructor is accessible, and all necessary implicit conversions are non-narrowing.


Foo foo2 = {4, 2}; 

これはcopy list initialization (6)です。明示的なコンストラクタは、非直接リストの初期化には考慮されません。これは、コンストラクターを明示的に変更したときにプログラムがコンパイルされなかった理由を説明しています。

copy-list-initialization (only non-explicit constructors may be called)

6) initialization of a named variable with a braced-init-list after an equals sign


Foo foo3 = Foo{4, 2}; 

そして、これは一時的なcopy initialization (1)から、一時オブジェクトのdirect list initialization (2)です。

direct-list-initialization (both explicit and non-explicit constructors are considered)

2) initialization of an unnamed temporary with a braced-init-list


Copy initialization is performed in the following situations:

2) when a named variable (automatic, static, or thread-local) of a non-reference type T is declared with the initializer consisting of an equals sign followed by an expression.


まず最も単純であり、私はそれを好む理由です。

2番目のメソッドは暗黙のコンストラクタを必要としますが、それ以外は問題ありません。

3回目はタイプの繰り返し(DRY違反)を含み、不要な一時的な構成を行います(実際には、オプティマイザによってコピーが省略される可能性がありますが、コピー可能でなければなりません)。

​​

暗黙的な変換を防止したい場合は、単一引数のコンストラクタを明示的に追加することをお勧めします。 Explicitは、2つの引数のコンストラクタに普遍的に有用ではありませんが、必要な場面が存在する可能性はありません。

関連する問題