不确定适当的标题,但它源于此讨论:
Do the parentheses after the type name make a difference with new?
在Visual Studio 2008上,当我运行以下代码时:
struct Stan
{
float man;
};
int main()
{
Stan *s1 = new Stan;
Stan *s2 = new Stan();
}
检查本地,s1有一个带有随机值的未初始化的浮点数。 s2的值初始化为0.
但是,如果我添加一个字符串数据成员,则两个实例中的float都是未初始化的。
struct Stan
{
std::string str;
float man;
};
但是,两个实例中的字符串都已初始化。我尝试添加其他非POD类而不是字符串,但后一种情况仅在我添加字符串数据成员时才会出现。我认为添加一个字符串仍然是一个POD类?如果它不是POD类,那么无论括号如何都应该初始化值,对吧?当我添加字符串数据成员时,没有初始化为什么浮动(以及其他原始数据类型)的想法?
答案 0 :(得分:5)
添加一个字符串会阻止struct成为POD类,因为POD类必须是一个聚合类,没有非POD-struct类型的成员,std::string
具有(除其他外)用户声明的构造函数使它成为非POD结构。
这是Visual Studio 2008的已知错误/功能。它不支持非POD类型的C ++ 03 值初始化,例如第二个示例中的结构。
对于第二个示例中的结构,应该发生的是,new Stan
没有初始化float,而是new Stan()
初始化为零。
通过在所有情况下调用该构造函数来初始化具有用户声明的默认构造函数的类型,这种情况正确发生。
答案 1 :(得分:0)
从C ++ 98语言规范的角度来看,您观察到的行为是一致的行为。
第一个示例中的类型是所谓的POD(普通旧数据)类型。将()
初始值设定项应用于POD类类型时,它会对类的所有数据成员执行零初始化。
第二个示例中的类型不是POD类型(因为非POD成员str
)。将()
初始化程序应用于非POD类类型时,它只是调用类构造函数来执行初始化。在您的情况下,隐式[编译器提供]构造函数将正确初始化str
成员,但不会对man
成员执行任何操作,这就是您在其中看到垃圾的原因。
同样,这是C ++ 98中的正确行为。它在C ++ 03中被改变了。在C ++ 03中,()
初始值设定项将执行值初始化。根据值初始化规则,在第二个示例中,man
字段也应该初始化为零,以响应()
初始值设定项。
有关更详细的说明,另请参阅https://stackoverflow.com/questions/1976185/what-is-the-difference-between-new-myclass-vs-new-myclass。