3

C++は、以下の例では、b1ために示したように、初期化リストを介して公衆のメンバーの値を設定し、クラスをインスタンス化することができ:C++:初期化リストによる構築はどのように行われますか?

class B { 
public: 
    int i; 
    std::string str; 
}; 

B b1{ 42,"foo" }; 
B b2(); 

。しかし、私がコンストラクタを提供する場合、

B(int k) { } 

はコンパイルされません。

だから、フードの後ろには何が起こっているのですか? コンストラクタが提供されていない場合、コンパイラはそれを提供しますか?しかし、どのように初期化リストを提供することができますか?私はそれが入力を取らない "空の"コンストラクタを提供すると思っていました。例ではb2のように表示されています。それとも両方を提供していますか?

答えて

5

しかし、どうすれば初期化リストを提供できますか?

いいえ、そうではありません。

list initializationB b1{ 42,"foo" };については、aggregate initializationが実行されます。

Tが集約タイプの場合、集約初期化が実行されます。

array type 
class type (typically, struct or union), that has 

    no private or protected non-static data members 
    no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed) 
    no virtual, private, or protected base classes 
    no virtual member functions 

なぜB b1{ 42,"foo" };作品もあります:

そしてB

集合体は、以下のいずれかのタイプで、aggregate typeです。

ユーザー定義のコンストラクタを指定すると、Bは非集計型になり、集約初期化は再び機能しません。この場合、BB b1{42};またはB b2(42);のように初期化することができ、適切なコンストラクタが呼び出されます。

BTW:ユーザー定義のコンストラクタ(1つのパラメータを使用)を指定した後、implicitly-declared default constructorはコンパイラによって再度宣言されません。つまり、B b2;またはB b2{};が再び機能しないことを意味します。

BTW2:B b2();は、関数宣言である可能性があります。 Most vexing parseを参照してください。

関連する問題