(转载)http://blog.csdn.net/xiajun07061225/article/details/8796257

我们在C++程序中经常看到两种new的使用方式:new A以及new A()。那么这两种究竟有什么区别呢?

调用new分配的内存有时候会被初始化,而有时候不会,这依赖于A的类型是否是POD(Plain old data)类型,或者它是否是包含POD成员、使用编译器生成默认构造函数的类。

附:POD类型

POD是Plain old data的缩写,它是一个struct或者类,且不包含构造函数、析构函数以及虚函数。

维基百科给出了更加详细的解释:

C++的POD类型或者是一个标量值,或者是一个POD类型的类。POD class没有用户定义的析构函数、拷贝构造函数和非静态的非POD类型的数据成员。而且,POD class必须是一个aggregate,没有用户定义的构造函数,没有私有的或者保护的非静态数据,没有基类或虚函数。它只是一些字段值的集合,没有使用任何封装以及多态特性。

附:aggregate的定义:

An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

接着介绍一下C++中的三种初始化方式:

zero-initialization,default-initialization,value-initialization。

首先需要注意的是value-initialization是在C++2003标准中新引入的,在原来的1998标准中并不存在。

C++03标准中针对这三种方式的说明:

To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
— if T is a union type, the object’s first named data member is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the object is zero-initialized.

To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized

A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed. If T is a cv-qualified type, the cv-unqualified version of T is used for these definitions of zero-initialization, default-initialization, and value-initialization.

注意:VS2008遵循的是98标准,而GCC3.4.5遵循的是03标准。

采用如下代码可以验证编译器遵循的到底是哪一种标准:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <new>
  4. struct A { int m; }; // POD
  5. struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
  6. struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
  7. int main()
  8. {
  9. char buf[sizeof(B)];
  10. memset( buf, 0x5a, sizeof( buf));
  11. // use placement new on the memset'ed buffer to make sure
  12. //  if we see a zero result it's due to an explicit
  13. //  value initialization
  14. B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
  15. //C++03 rules - pB->m is set to 0
  16. printf( "m  is %d\n", pB->m);
  17. return 0;
  18. }

在VS008中输出就不是0,说明遵循的是98标准。

下面先看一段C++示例代码:

  1. #include <iostream>
  2. using namespace std;
  3. struct A { int m; }; // POD
  4. struct B { ~B(){}; int m; }; // non-POD, compiler generated default ctor
  5. struct C { C() : m() {}; ~C(){}; int m; }; // non-POD, default-initialising m
  6. int main()
  7. {
  8. A *aObj1 = new A;
  9. A *aObj2 = new A();
  10. cout << aObj1->m << endl;
  11. cout << aObj2->m << endl;
  12. B *bObj1 = new B;
  13. B *bObj2 = new B();
  14. cout << bObj1->m << endl;
  15. cout << bObj2->m << endl;
  16. C *cObj1 = new C;
  17. C *cObj2 = new C();
  18. cout << cObj1->m << endl;
  19. cout << cObj2->m << endl;
  20. delete aObj1;
  21. delete aObj2;
  22. delete bObj1;
  23. delete bObj2;
  24. delete cObj1;
  25. delete cObj2;
  26. return 0;
  27. }

运行结果:

上述测试平台是VS2008.需要注意的是,VS08只支持C++98。

在这种情况下:

new A:不确定的值

new A():zero-initialize

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

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

new C:默认构造(C::m被zero-initialize)

new C():默认构造(C::m被zero-initialize)

如果用兼容C++03的编译器,比如G++结果:

new A:不确定的值

new A():value-initialize A,由于是POD类型所以是zero initialization

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

new B():value-initialize B,zero-initialize所有字段,因为使用的默认构造函数

new C:default-initialize C,调用默认构造函数

new C():value-initialize C,调用默认构造函数

在所有C++版本中,只有当A是POD类型的时候,new A和new A()才会有区别。而且,C++98和C++03会有区别。

参考资料:

What are POD types in C++?

What are Aggregates and PODs and how/why are they special?

(转载)【C++】new A和new A()的区别详解的更多相关文章

  1. Go学习——new()和 make()的区别详解(转载)

    这篇文章主要介绍了Go语言中new()和 make()的区别详解,本文讲解了new 的主要特性.make 的主要特性,并对它们的区别做了总结,需要的朋友可以参考下 概述 Go 语言中的 new 和 m ...

  2. 【转载】JAVA消息服务JMS规范及原理详解

    转载:https://www.cnblogs.com/molao-doing/articles/6557305.html 作者: moyun- 一.简介 JMS即Java消息服务(Java Messa ...

  3. [转载]领域驱动设计(Domain Driven Design)参考架构详解

    摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces.Applications和Domain三层以及包含各类基础设施的Infrast ...

  4. 【转载】图说C++对象模型:对象内存布局详解

    原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在 ...

  5. 【转载】chrome控制台中看见的cookie属性详解

    在chrome控制台中的resources选项卡中可以看到cookie的信息. 一个域名下面可能存在着很多个cookie对象. name字段为一个cookie的名称. value字段为一个cookie ...

  6. 转载:@RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    转载自:https://blog.csdn.net/walkerjong/article/details/7946109#commentBox   因为写的很好很全,所以转载过来 引言:接上一篇文章, ...

  7. 《转载》Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解

    引言: 接上一篇文章,对@RequestMapping进行地址映射讲解之后,该篇主要讲解request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用: 简介: han ...

  8. [转载]java之yield(),sleep(),wait()区别详解

    原文地址:http://dylanxu.iteye.com/blog/1322066 1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁 ...

  9. (转载)linux中设备文件配置程序udev详解

    如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Linux改变了几次策略.在Linux早期,设备文件仅仅是是一些带有适当的属性集的普通文件,它由mknod命令创建,文件存放在/dev ...

随机推荐

  1. Jetty 与 Tomcat 比较,及性能分析

    主流java的web容器,主要是Tomcat, jboss, jetty, resin.由于以前我们主要用的是jboss4.0.5,但jbosse用的servlet容器是tomcat5.5,所以只进行 ...

  2. python学习笔记13(模块、包)

    在Python中有一个概念叫做模块(module),比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块. 模块文件以.py后缀结 ...

  3. BZOJ 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果

    Description 每年万圣节,威斯康星的奶牛们都要打扮一番,出门在农场的N(1≤N≤100000)个牛棚里转悠,来采集糖果.她们每走到一个未曾经过的牛棚,就会采集这个棚里的1颗糖果. 农场不大, ...

  4. What is an eigenvector of a covariance matrix?

    What is an eigenvector of a covariance matrix? One of the most intuitive explanations of eigenvector ...

  5. HDU1353+贪心

    注意精度. /* */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<al ...

  6. cocos2dx Sprite setBlendFunc 使用颜色混合:加算,减算

    说明: 图片的混色是游戏的特效的特破口,应用的好,可以大量减少图片的使用量,有专门的介绍资料... setBlendFunc  相关参数,有多种组合方式,需要经验的积累 http://blog.csd ...

  7. netstat命令查看服务器运行情况

    netstat -n|grep 80出现大量time_wait 在运行netstat -n|grep 80 | awk '/^tcp/ {++S[$NF]} END {for(a in S) prin ...

  8. SRM 587 DIV1

    要掉到DVI2了..好不容这次的250那么简单,500的题知道怎么做,可惜没调出来500. 250的题很简单,从第1步到第N步,每次要么不做,要么走i步,且X不能走,问说最远走多远. #include ...

  9. Use powerful plugins in your vim.

    # setup by root wget http://prdownloads.sourceforge.net/ctags/ctags-5.8.tar.gz tar -xzvf ctags-5.8.t ...

  10. linux0.11文件分析

    在kernel包中有几个重要的文件夹和文件,他们各司其职,处理着有关内核的一些功能操作.其中文件夹有三个:blk_drv(块设备驱动),chr_drv(字符设备驱动),math(数学协处理器)  文件 ...