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)让我们读得更快。但如果需要准确理解,还是建议读一读原文。
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)让我们读得更快。但如果需要准确理解,还是建议读一读原文。
相关文章推荐
- new创建一个对象,是否需要加括号?
- c++对象创建后面是否括号
- JAVA中对于需要频繁new的对象的一个优化的方法
- 虚拟机是如何判断一个对象是否需要回收
- php new 对象是否带括号的区别
- Java中创建String、Integer、Charater直接赋值与new一个对象的区别
- C# 在两个不同的方法里面Lock同一个锁对象,是否需要线程等待?
- new创建一个对象时,详细的过程是怎么样的
- 6-2-1 字符串-字符串变量String-创建字符串变量-初始化字符串变量-字符串连接-输入字符串(单词、行)-对象变量的赋值-比较两个字符串是否同一个-比较两个字符串内容是否相同
- java中用new创建一个对象的过程解析
- new一个类对象和使用类名创建一个对象有什么区别?
- new Object[5]语句是否创建了5个对象
- close操作前要测试“文件对象”是否创建成功,如果多个流,需要分别去关闭
- 面试题:Student s = new Student();在内存中做了哪些事情?即创建一个对象做了哪些事情
- 编写高质量代码改善C#程序的157个建议——建议10: 创建对象时需要考虑是否实现比较器
- C++中new 一个对象的时候加括号和不加括号的区别
- C++中new 一个对象的时候加括号和不加括号的区别
- 创建一个对象 new 与 不加new 有什么区别
- 在spring 中如果使用new创建一个对象时 这个对象将不在受spring管理器管理
- 面试题:Student s = new Student();在内存中做了哪些事情?即创建一个对象做了哪些事情