类型名称后的括号是否与 new 不同?

如果'Test'是一个普通的类,有什么区别:

If 'Test' is an ordinary class, is there any difference between:

Test* test = new Test;

Test* test = new Test();

推荐答案

让我们学以致用,因为存在实际上会影响代码行为的差异.以下大部分内容来自对旧新事物"文章的评论.

Let's get pedantic, because there are differences that can actually affect your code's behavior. Much of the following is taken from comments made to an "Old New Thing" article.

有时 new 运算符返回的内存会被初始化,有时它不会取决于您要更新的类型是否为 POD(普通旧数据),或者如果它是一个包含 POD 成员并且使用编译器生成的默认构造函数的类.

Sometimes the memory returned by the new operator will be initialized, and sometimes it won't depending on whether the type you're newing up is a POD (plain old data), or if it's a class that contains POD members and is using a compiler-generated default constructor.

  • 在 C++1998 中有 2 种类型的初始化:零和默认
  • 在 C++2003 中添加了第三种初始化类型,即值初始化.

假设:

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

在 C++98 编译器中,应发生以下情况:

In a C++98 compiler, the following should occur:

  • new A - 不确定值
  • new A() - 零初始化

  • new A - indeterminate value
  • new A() - zero-initialize

new B - 默认构造(B::m 未初始化)

new B - default construct (B::m is uninitialized)

new B() - 默认构造(B::m 未初始化)

new B() - default construct (B::m is uninitialized)

new C - 默认构造(C::m 初始化为零)

new C - default construct (C::m is zero-initialized)

在符合 C++03 的编译器中,事情应该是这样的:

In a C++03 conformant compiler, things should work like so:

  • new A - 不确定值
  • new A() - value-initialize A,因为它是 POD,所以是零初始化.

  • new A - indeterminate value
  • new A() - value-initialize A, which is zero-initialization since it's a POD.

new B - 默认初始化(使 B::m 未初始化)

new B - default-initializes (leaves B::m uninitialized)

new B() - 值初始化 B,它将所有字段初始化为零,因为它的默认 ctor 是编译器生成的,而不是用户定义的.

new B() - value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

new C - 默认初始化 C,调用默认 ctor.

new C - default-initializes C, which calls the default ctor.

因此,在所有版本的 C++ 中,new Anew A() 之间存在差异,因为 A 是 POD.

So in all versions of C++ there's a difference between new A and new A() because A is a POD.

对于 new B() 的情况,C++98 和 C++03 之间的行为存在差异.

And there's a difference in behavior between C++98 and C++03 for the case new B().

这是 C++ 中尘土飞扬的角落之一,会让你发疯.在构造对象时,有时您想要/需要括号,有时您绝对不能拥有它们,有时这无关紧要.

This is one of the dusty corners of C++ that can drive you crazy. When constructing an object, sometimes you want/need the parens, sometimes you absolutely cannot have them, and sometimes it doesn't matter.

相关文章