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

标签 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;
}

当我这样做时,_a 被垃圾初始化。为什么会这样?从另一个构造函数中调用构造函数时会出现问题吗?

最佳答案

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

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

调用默认的Test构造函数,然后设置_b = t。相反,它使用默认构造函数创建类型为 Test 的临时对象,忽略该临时对象,然后设置 _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;
};

希望这对您有所帮助!

关于c++ - 不同构造函数中的构造函数调用产生错误数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17226637/

相关文章:

c++ - C++ 中的命名空间类模板继承

c++ - 在一行中创建一个前缀序列

C++快速刷新桌面

json - f# 类构造函数格式

c++ - 我想从此代码中删除 using namespace std,但我不确定所有需要以 std::为前缀的内容

C++ 如何将字符指针数组转换为字符串数组?

java - 默认构造函数无法处理抛出的异常类型 IOException

c++ - cpp中的构造函数无限循环

javascript - 为什么我的构造函数没有继承 super 构造函数的方法?

java - 有没有 "UNIVERSAL"方法来初始化对象数组? ( java )