您的位置:首页 > 其它

new创建一个对象,是否需要加括号?

2013-10-06 21:34 316 查看
转自

http://blog.csdn.net/eastcowboy/article/details/8105658

原文链接:http://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new/



问:假设有class Test,那么以下两种写法有何不同?

写法1、Test* test = new Test;

写法2、Test* test = new Test();



答:这需要很细致的专研,因为两种写法的区别虽然细微,但会导致不同的运行结果。Test是否是POD类型,是否包含POD成员并且采用编译器自动产生的默认构造函数,都会关系到new分配得到的内存是否初始化。

在C++98标准中,有两种初始化,即zero initialization和default initialization。(概念、术语,不知道该怎么翻译,保留英文原文)

在C++03标准中,还新增了第三种,即value initialization。

以上三种initialization的区别,参见译注第2条。



考虑这段代码:

[cpp] view
plaincopyprint?

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标准中,会是这样:

new A - m的值不确定

new A() - m的值为零

new B - default construct (m没有被初始化)

new B() - default construct (m没有被初始化)

new C - default construct (m初始化为零)

new C() - default construct (m初始化为零)



在C++03标准中,会是这样:

new A - m的值不确定

new A() - 进行value initialization,由于A是POD类型,所以实际上执行zero initialization,结果m初始化为零

new B - 进行default initialization,m没有被初始化

new B() - 进行value initialization,因为构造函数是编译器自动产生(而不是用户自己定义),所以会对所有成员执行zero initialization,结果m初始化为零

new C - 进行default initialization,调用构造函数,m初始化为零

new C() - 进行value initialization,调用构造函数,m初始化为零



综合起来看,有两个需要注意的地方:

1、在两种C++标准中,对于POD类型struct A来说,new A和new A()的结果会不同。写了括号会把结构体的成员赋值为零,没写括号就不会。

2、对于new B(),在C++98标准和C++03标准的行为不一致。前者不会把成员变量初始化为零,而后者会。



这是C++的阴暗角落之一,不小心的话可能会让你发疯。用new创建对象时,有时需要加括号,有时基本不能加括号,有时不管加不加括号皆可。







译注:

1、经Visual Studio 2008试验,int* p1 = new int; int* p2 = new int();,则*p1是一个不确定的值,而*p2等于零。

2、什么叫default initialization,什么叫value initialization,什么叫zero initialization,这里还有一篇。http://stackoverflow.com/questions/7084831/difference-between-default-initialize-and-value-initialize-in-c03。大致翻译如下:

zero initialization的定义:对于标量类型(scalar type),初始化为零;对于non-union的class(或者struct)类型,每个成员和每个基类都进行zero initialization(递归定义);对于数组,每个成员都进行zero initialization(递归定义);对于union,第一个成员被zero initialization;对于引用,不执行任何动作。

default initialization的定义:对于non-POD类型,调用默认构造函数(若默认构造函数不能访问,则出错);对于数组,每个成员都进行default initialization(递归定义);其它情形,视作与zero initialization一致。

value initialization的定义:如果有用户定义的构造函数,则调用默认构造函数(若默认构造函数不能访问,则出错);对于non-union的class(或者struct)类型,且没有用户定义的构造函数,每个成员和每个基类都进行value initialization;对于数组,每个成员都进行value initialization;其它情形,视作与zero initialization一致。

3、翻译有些许遗漏,只记录了我觉得比较重要的内容。这里翻译的作用主要是:(1)备忘;(2)让更多人知道;(3)让我们读得更快。但如果需要准确理解,还是建议读一读原文。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐