我对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
答案 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本身。