【发布时间】:2009-10-17 08:47:35
【问题描述】:
在 C++ 中,以下两个动态对象创建之间的确切区别是什么:
A* pA = new A;
A* pA = new A();
我做了一些测试,但似乎在这两种情况下,都调用了默认构造函数,并且只调用了它。我正在寻找有关性能的任何差异...
谢谢
【问题讨论】:
标签: c++
在 C++ 中,以下两个动态对象创建之间的确切区别是什么:
A* pA = new A;
A* pA = new A();
我做了一些测试,但似乎在这两种情况下,都调用了默认构造函数,并且只调用了它。我正在寻找有关性能的任何差异...
谢谢
【问题讨论】:
标签: c++
如果 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被值初始化时,因为它没有使用声明的构造函数,它的所有成员都被值初始化这意味着@的默认构造函数987654333@ 被调用并且a 被零初始化。
ISO 14882:2003 参考:
5.3.4 [expr.new]/15:new 表达式分配的对象如何根据初始化器是否省略、一对括号或其他方式进行初始化。
8.5 [dcl.init]/5:零初始化、默认初始化和值初始化的含义。 p>
12.1 [class.ctor]/7,8:用户编写的构造函数的形式,与隐式定义的默认构造函数的行为相匹配。
12.6.2 [class.base.init]/4:未在构造函数的成员初始化器列表中列出的基类和成员如何初始化。
【讨论】:
new A 和new A() 之间的区别移至“是否有用户声明的构造函数”行。在原始 C++ 标准 (C++98) 中没有“值初始化”,两者之间的差异由 POD/非 POD 属性定义。根据您的编译器所遵循的语言规范,您可能会得到不同的结果。顺便说一句,上面的struct A 就是一个例子。
完全一样,性能方面也一样:)
【讨论】:
在第一个版本中,词法分析器必须少扫描两个字符,因此编译过程要快一点;)
【讨论】:
请看 STL 实现代码(例如分配器)然后你就会明白。
【讨论】: