不同构造函数中的构造函数调用产生错误数据

wjm*_*wjm 3 c++ constructor

以下是复制我的问题的最小程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

当我这样做时,_a用垃圾初始化.为什么会这样?从另一个构造函数调用构造函数时是否存在问题?

tem*_*def 10

这里的问题是在这段代码中:

Test(int t)
{
    Test();
    _b = t;
}
Run Code Online (Sandbox Code Playgroud)

这并不会调用默认的Test构造函数,然后设置_b = t.相反,它Test使用默认构造函数创建一个类型的临时对象,忽略该临时对象,然后设置_b = t.因此,默认构造函数不会为接收器对象运行,因此_a将保持未初始化状态.

要解决这个问题,可以在C++ 11中编写

Test(int t) : Test() {
    _b = t;
}
Run Code Online (Sandbox Code Playgroud)

它可以调用默认构造函数,或者(在C++ 03中)您可以将默认构造函数中的初始化代码分解为从默认构造函数和参数化构造函数调用的辅助成员函数:

Test() {
    defaultInit();
}
Test(int t) {
    defaultInit();
    _b = t;
}
Run Code Online (Sandbox Code Playgroud)

或者,如果你有一个C++ 11编译器,只需使用默认初始化器消除默认构造函数,如下所示:

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

希望这可以帮助!