当我运行这段代码时,VS编译器返回错误,并说t1.mem
是未初始化的局部变量。
#include <string>
#include <iostream>
struct T1
{
int mem;
};
struct T2
{
int mem;
T2() { } // "mem" is not in the initializer list
};
int main()
{
T1 t1; // class, calls implicit default ctor
std::cout << t1.mem << std::endl;
const T2 t2; // const class, calls the user-provided default ctor
// t2.mem is default-initialized (to indeterminate value)
std::cout << t2.mem << std::endl;
}
如果我没有为结构T1
分配构造函数,编译器必须生成默认构造函数?而struct T2
的构造函数是空的初始化列表,为什么它没有错误提示?
2条答案
按热度按时间c0vxltue1#
我的理解是,编译器试图保护你免受它自己生成的代码的影响,并在使用你提供的构造函数时假设“你最了解”。此外,检查构造函数是否在任何地方初始化
T2.mem
,包括在构造函数的主体中,可能是一个任意复杂的任务,因此编译器作者可能认为这是一个最好不要尝试的任务,而不是执行得很差。如果你将
t1
声明为const T1
,那么MSVC的warning you would get似乎也支持这一点:用编译器生成的默认构造函数初始化的“const”自动数据产生不可靠的结果
请注意“编译器生成的默认构造函数”这一措辞。
顺便说一句,如果你用
T2() = default
请求编译器生成的默认构造函数,你会看到同样的警告。s2j5cfk02#
编译器并不完美。有时候他们警告一件事,但他们不为另一个,类似的事情。许多编译器还提供生成代码的运行时插装,在那里它们插入特殊的指令来检测错误,如使用未初始化的变量,并在发生这种情况时中止程序。但同样,这个系统并不完美,它可能会错过一些东西。
在任何情况下,您实际上都不需要构造函数。你可以内联初始化类成员:
默认情况下,将使用内联初始化,除非构造函数将成员转换为其他内容: