A* pA = new A; 和 A* pA = new A(); 之间的区别是什么?

21

在C++中,以下两种动态对象创建方式有什么确切的区别:

A* pA = new A;

A* pA = new A(); 

我进行了一些测试,但在两种情况下都只发现调用了默认构造函数。我正在寻找关于性能的任何差异...

谢谢

4个回答

39
如果A是POD类型,那么new A将会分配一个新的A对象但会保留一个不确定的值。否则,new A将会使用默认值初始化这个新对象。
在所有情况下,new A()将会对新的A对象进行值初始化。
这显然对于POD类型有着不同的行为,但也影响到了没有使用自定义构造函数的非POD、非联合类类型。
例如:
struct A
{
    int a;
    std::string s;
};

A是一个非POD类类型,没有用户声明的构造函数。当一个A默认初始化时,隐式定义的构造函数被调用,该构造函数为s(非POD类型)调用了默认构造函数,但a没有被初始化。

当一个A值初始化时,由于它没有用户声明的构造函数,所以它的所有成员都会值初始化,这意味着会调用s的默认构造函数,而a则被零初始化

ISO 14882:2003参考:

  • 5.3.4 [expr.new]/15:根据初始化器是否省略、是否为一对括号或其他方式来初始化由new表达式分配的对象。

  • 8.5 [dcl.init]/5:零初始化、默认初始化和值初始化的含义。

  • 12.1 [class.ctor]/7,8:与隐式定义的默认构造函数行为匹配的用户自定义构造函数的形式。

  • 12.6.2 [class.base.init]/4:如何初始化不在构造函数的成员初始化器列表中列出的基类和成员。


2
和,实际上措辞有些混乱。POD是什么鬼? - hasen
“Plain old data”是C++中非常重要的概念,其缩写在标准中被广泛使用。对于措辞不当我深感抱歉。 - CB Bailey
3
注意,“值初始化”的概念是在修订的 C++ 标准中引入的。这也将new Anew A()之间的区别移动到“是否有用户声明的构造函数”这一行。在原始的 C++ 标准(C++98)中,不存在“值初始化”,两者之间的区别是由 POD/非-POD 属性定义的。根据您的编译器遵循的语言规范,可能会得到不同的结果。顺便说一下,上面的 struct A 是一个例子。 - AnT stands with Russia

0

在第一个版本中,词法分析器将少扫描两个字符,因此编译过程会稍微快一些;)


-1
请查看STL实现代码(例如分配器),然后您就会理解。

-1

完全一样,性能也一样好 :)


2
这完全是不正确的。对于POD类型和没有用户定义构造函数的非POD类类型,这两个表达式具有不同的效果。 - CB Bailey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接