3

以下は、私の問題を再現する最小のプログラムです。

#include <iostream>

using namespace std;

class Test
{
public:
    Test()
    {
        _a = 0;
    }
    Test(int t)
    {
        Test();
        _b = t;
    }
    void Display()
    {
        cout << _a << ' ' << _b << endl;
    }
private:
    int _a;
    int _b;
};

int main()
{
    Test test(10);
    test.Display(); // 70 10

    return 0;
}

これを行う_aと、ガベージで初期化されます。なぜこれが起こるのですか?コンストラクターが別のコンストラクター内から呼び出されたときに問題はありますか?

4

1 に答える 1

10

ここでの問題は、次のコードにあります。

Test(int t)
{
    Test();
    _b = t;
}

これは、デフォルトのコンストラクターを呼び出してから set を呼び出しませ。代わりに、デフォルトのコンストラクターを使用して type の一時オブジェクトを作成し、その一時オブジェクトを無視してから、 を設定します。したがって、既定のコンストラクターはレシーバー オブジェクトに対して実行されないため、初期化されないままになります。Test_b = tTest_b = t_a

これを修正するには、C++11 で次のように記述します。

Test(int t) : Test() {
    _b = t;
}

既定のコンストラクターを呼び出すか、(C++03 では) 初期化コードを既定のコンストラクターから、既定のコンストラクターとパラメーター化されたコンストラクターの両方から呼び出すヘルパー メンバー関数に分解できます。

Test() {
    defaultInit();
}
Test(int t) {
    defaultInit();
    _b = t;
}

または、C++11 コンパイラを使用している場合は、次のように、既定の初期化子を使用して既定のコンストラクターを削除します。

class Test
{
public:
    Test() = default;
    Test(int t)
    {
        _b = t;
    }
    void Display()
    {
        cout << _a << ' '<< _b << endl;
    }
private:
    int _a = 0;
    int _b;
};

お役に立てれば!

于 2013-06-21T02:05:46.717 に答える