日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

new A和new A()的区别详解

發布時間:2024/4/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 new A和new A()的区别详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我們在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標準。

采用如下代碼可以驗證編譯器遵循的到底是哪一種標準:

[cpp]?view plaincopyprint?
  • #include?<stdio.h>??
  • #include?<string.h>??
  • #include?<new>??
  • ??
  • 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??
  • ??
  • int?main()??
  • {??
  • ????char?buf[sizeof(B)];??
  • ????memset(?buf,?0x5a,?sizeof(?buf));??
  • ??
  • ????//?use?placement?new?on?the?memset'ed?buffer?to?make?sure???
  • ????//??if?we?see?a?zero?result?it's?due?to?an?explicit???
  • ????//??value?initialization??
  • ????B*?pB?=?new(buf)?B();???//C++98?rules?-?pB->m?is?uninitialized??
  • ????????????????????????????//C++03?rules?-?pB->m?is?set?to?0??
  • ????printf(?"m??is?%d\n",?pB->m);??
  • ????return?0;??
  • }??
  • 在VS008中輸出就不是0,說明遵循的是98標準。



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

    [cpp]?view plaincopyprint?
  • #include?<iostream>??
  • ??
  • using?namespace?std;??
  • ??
  • 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??
  • ??
  • int?main()??
  • {??
  • ????A?*aObj1?=?new?A;??
  • ????A?*aObj2?=?new?A();??
  • ????cout?<<?aObj1->m?<<?endl;??
  • ????cout?<<?aObj2->m?<<?endl;??
  • ??
  • ????B?*bObj1?=?new?B;??
  • ????B?*bObj2?=?new?B();??
  • ????cout?<<?bObj1->m?<<?endl;??
  • ????cout?<<?bObj2->m?<<?endl;??
  • ??
  • ????C?*cObj1?=?new?C;??
  • ????C?*cObj2?=?new?C();??
  • ????cout?<<?cObj1->m?<<?endl;??
  • ????cout?<<?cObj2->m?<<?endl;??
  • ??
  • ????delete?aObj1;??
  • ????delete?aObj2;??
  • ????delete?bObj1;??
  • ????delete?bObj2;??
  • ????delete?cObj1;??
  • ????delete?cObj2;??
  • ??
  • ????return?0;??
  • }??
  • 運行結果:



    上述測試平臺是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會有區別。

    總結

    以上是生活随笔為你收集整理的new A和new A()的区别详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。