C ++中的默认初始化

时间:2010-02-08 19:11:47

标签: c++

我对C ++中的默认初始化有疑问。我被告知非POD对象将自动初始化。但我对以下代码感到困惑。

为什么当我使用指针时,变量i被初始化为0,但是,当我声明一个局部变量时,它不是。我使用g ++作为编译器。

class INT {
    public: int i;

};

int main () {

    INT* myint1 = new INT;
    INT myint2;
    cout<<"myint1.i is "<<myint1->i<<endl;
    cout<<"myint2.i is "<<myint2.i<<endl;

    return 0;
}

输出

myint1.i为0

myint2.i是-1078649848

7 个答案:

答案 0 :(得分:8)

你需要在INT中声明一个c'tor并强制'i'到一个明确定义的值。

class INT {
public:

    INT() : i(0) {}

 ...
};

i仍然是POD,因此默认情况下不会初始化。无论是在堆栈上还是从堆中分配都没有区别 - 在这两种情况下,如果i未定义,则无关。

答案 1 :(得分:6)

在这两种情况下都没有初始化,你很幸运在第一个中得到0

答案 2 :(得分:2)

首先,您的班级INT是POD。

其次,当某些内容“自动初始化”时(对于自动或动态对象),这意味着会自动调用构造函数。没有其他“自动”初始化方案(对于自动或动态对象);所有其他方案都需要“手动”指定的初始化程序。但是,如果构造函数没有执行任何操作来执行所需的初始化,则不会进行该初始化。必要时,您有责任编写该构造​​函数。

在您的示例中,您应该在对象中获得垃圾。在新编辑的情况下你观察到的0完全是偶然的。

答案 3 :(得分:2)

这取决于编译器。这里最大的区别是设置为new Something的指针指的是堆中的某些内存区域,而局部变量存储在堆栈中。也许你的编译器会将堆内存归零,但不会打扰堆栈内存;无论哪种方式,你都不能指望任何一种方法归零你的记忆。您应该使用Win32中的ZeroMemory或C标准库中的memset来清零内存,或者在INT的构造函数中设置i = 0.

答案 4 :(得分:2)

对于类或结构类型,如果在定义变量时没有告诉它使用哪个构造函数,则调用默认构造函数。如果您没有定义默认构造函数,那么编译器会为您创建一个。如果类型不是类(或结构)类型,那么它不会被初始化,因为它没有构造函数,更不用说默认构造函数了(因此没有像int这样的内置类型将被默认初始化)。 / p>

因此,在您的示例中,myint1和myint2都是使用编译器为INT声明的默认构造函数构造的。但由于这不会初始化INT中的任何非类/结构变量,因此INT的i成员变量未初始化。

如果你想要初始化我,你需要为INT编写一个默认的构造函数来初始化它。

答案 5 :(得分:1)

我们刚才有了这个主题,您可以找到一些解释here

如果向类中添加更多变量,最终会得到未初始化的成员变量。

答案 6 :(得分:1)

非POD对象也是如此,但你的对象是POD,因为它没有用户定义的构造函数,只包含POD本身。