5
class A {
public:
    A(int v) {
        _val = v;
    }

private:
    int _val;
};

class B {
public:
    B(int v) {
        a = A(v); // i think this is the key point
    }

private:
    A a;
};

int main() {
    B b(10);

    return 0;
}

コンパイラは言う:

test.cpp: In constructor ‘B::B(int)’:
test.cpp:15: error: no matching function for call to ‘A::A()’
test.cpp:5: note: candidates are: A::A(int)
test.cpp:3: note:                 A::A(const A&)

私はJavaを学びましたが、C++でこれに対処する方法がわかりません。数日検索すると、plzはC ++でこれを実行できると教えてくれますか?

4

3 に答える 3

16

メンバー初期化リストを使用する必要があります

B(int v):a(v)
{
}

と:

B(int v) 
{
        a = A(v); // i think this is the key point
}

a値が割り当てられており、初期化されていません(これは意図したことです)。コンストラクターの本体が開始される{と、そのすべてのメンバーは既に構築されています。

エラーが発生するのはなぜですか?
コンパイラは、aコンストラクタ本体{が始まる前に構築します。コンパイラは、別のA方法で指定しなかったため、引数なしのコンストラクタを使用します注 1、デフォルトの引数なしのコンストラクタが使用できないため、エラーが発生します。

デフォルトの引数なしコンストラクターが暗黙的に生成されないのはなぜですか?
クラスにコンストラクターを提供する、暗黙的に生成された引数のないコンストラクターは生成されなくなります。コンストラクターのオーバーロードを提供しAたため、引数のないコンストラクターの暗黙的な生成はありません。

注 1
メンバー初期化子リストの使用は、デフォルトの引数なしコンストラクターではなく、特定のオーバーロードされたバージョンのコンストラクターを使用するようコンパイラーに指示する方法です。

于 2012-05-28T11:24:37.113 に答える
7

初期化リストを使用する必要があります。

class B {
public:
    B(int v) : a(v) { // here

    }

private:
    A a;
};

Aそれ以外の場合、コンパイラはデフォルトのコンストラクターを使用してを構築しようとします。提供していないため、エラーが発生します。

于 2012-05-28T11:24:53.023 に答える
2

はい、できますが、デフォルトのコンストラクターA(パラメーターを受け取らないか、すべてのパラメーターにデフォルト値がある)を提供していないため、初期化リストでのみ初期化できます。

B(int v) : a(v) 
{
}

これは、コンストラクター本体が入る前にa、デフォルトのコンストラクター(使用不可)を使用して構築(または構築が試行)されるためです。

于 2012-05-28T11:24:00.183 に答える