[解決済み] デフォルト、値、ゼロ初期化ガチャ
質問
値やデフォルト、ゼロ初期化について非常に混乱しています。 特に、異なる標準のためにそれらが起動するとき C++03 と C++11 (そして C++14 ).
私は本当に良い答えを引用し、拡張しようとしています。 値-/デフォルト-/ゼロ- 初期値 C++98 と C++03 というのは、もし誰かが必要なギャップを埋めるのを手伝ってくれて、いつ何が起こるかについての良い概要を持つことができれば、多くのユーザーを助けることができるからです。
一言で言えば、例による完全な洞察です。
new 演算子によって返されるメモリは、初期化されることもあれば、初期化されないこともあります。これは、新規作成される型が POD (プレーンオールドデータ) であるか、または POD メンバを含むクラスでコンパイラが生成したデフォルト コンストラクタを使用しているかによって異なります。
- で C++1998 には、2 種類の初期化があります。 ゼロ と デフォルト初期化
- で C++2003 では、3 番目のタイプの初期化です。 値による初期化 が追加されました。
- で c++2011/c++2014 のみ リスト初期化 のルールが追加され 値/デフォルト/ゼロの初期化 が少し変更されました。
想定してください。
struct A { int m; };
struct B { ~B(); int m; };
struct C { C() : m(){}; ~C(); int m; };
struct D { D(){}; int m; };
struct E { E() = default; int m;}; /** only possible in c++11/14 */
struct F {F(); int m;}; F::F() = default; /** only possible in c++11/14 */
C++98コンパイラでは、以下のようになります。 :
-
new A
- 不定値(A
はPOD) -
new A()
- ゼロイニシャライズ -
new B
- デフォルトコンストラクト (B::m
は初期化されません。B
は非POD) -
new B()
- デフォルトの構成 (B::m
は初期化されない) -
new C
- デフォルトコンストラクト (C::m
はゼロ初期化されます。C
は非POD) -
new C()
- デフォルトの構成 (C::m
はゼロ初期化) -
new D
- デフォルトコンストラクト (D::m
は初期化されません。D
は非POD) -
new D()
- デフォルトの構成? (D::m
は初期化されません)
C++03に準拠したコンパイラでは、このように動作するはずです。
-
new A
- 不定値(A
はPOD) -
new A()
- 値初期化A
というのは、PODなのでゼロ初期化です。 -
new B
- デフォルトの初期化 (葉B::m
は未初期化です。B
は非POD) -
new B()
- 値による初期化B
これは、デフォルトの Ctor がユーザー定義ではなく、コンパイラによって生成されるため、全てのフィールドをゼロ初期化します。 -
new C
- デフォルトで初期化するC
で、これはデフォルトの ctor を呼び出します。(C::m
はゼロ初期化されます。C
は非POD) -
new C()
- 値による初期化C
で、これはデフォルトのコー タを呼び出します。 (C::m
はゼロ初期化) -
new D
- デフォルトコンストラクト (D::m
は初期化されません。D
は非POD) -
new D()
- 値を初期化する D? で、これはデフォルトのコー タを呼び出します (D::m
は初期化されない)
斜体の値と?は不確定要素なので、修正にご協力ください :-)
C++11 準拠のコンパイラでは、このように動作するはずです。
??? (ここから始めると、どうせうまくいかないので、助けてください)
C++14 準拠のコンパイラでは、このように動作するはずです。 ??? (ここから始めると、どうせうまくいかないので、助けてください) (回答に基づいてドラフト)
-
new A
- デフォルトの初期化A
コンパイラ gen. ctor, (leavsA::m
未初期化) (A
はPOD) -
new A()
- 値による初期化A
にある点なので、ゼロ初期化です。 [dcl.init]/8 -
new B
- デフォルトの初期化B
コンパイラ gen.ctor, (leavs)B::m
未初期化) (B
は非POD) -
new B()
- 値による初期化B
これは、そのデフォルトのCTORがユーザー定義ではなく、コンパイラが生成したものであるため、全てのフィールドをゼロ初期化します。 -
new C
- デフォルトの初期化C
で、これはデフォルトの ctor を呼び出します。(C::m
はゼロ初期化されます。C
は非POD) -
new C()
- 値による初期化C
で、これはデフォルトのコー タを呼び出します。(C::m
はゼロ初期化) -
new D
- デフォルトの初期化D
(D::m
は初期化されていません。D
は非POD) -
new D()
- 値による初期化D
であり、デフォルトの Ctor (D::m
は初期化されない) -
new E
- デフォルトの初期化E
であり、コンパイル元CTORを呼び出しています。(E::m
は初期化されていない、Eは非POD) -
new E()
- 値による初期化E
を初期化し、ゼロ初期化E
で2点なので [dcl.init]/8 ) -
new F
- デフォルトの初期化F
であり、コンパイル元CTORを呼び出しています。(F::m
は初期化されていません。F
は非POD) -
new F()
- 値による初期化F
であり、これは デフォルト初期化F
での1.ポイントから [dcl.init]/8 (F
ctor関数は、ユーザが宣言し、最初の宣言で明示的にデフォルトまたは削除されない場合、ユーザが提供するものです。 リンク )
どのように解決するのですか?
C++14 では、以下の方法で作成されたオブジェクトの初期化が規定されています。
new
で作成されたオブジェクトの初期化を指定します(C++11 では [expr.new]/15 で、当時は注記ではなく規範的なテキストでした)。
A 新しい式 型のオブジェクトを作成する
T
はそのオブジェクトを次のように初期化します。 オブジェクトを次のように初期化します。
- もし 新イニシャライザー が省略された場合、そのオブジェクトは default-initializedとなります。 (8.5). [ 注意してください。 初期化が行われない場合 が実行されない場合、オブジェクトは不定な値を持つ。 - エンドノート ]
- それ以外の場合は 新イニシャライザー は、8.5の初期化のルールに従って解釈され 直接初期化 .
Default-initialization は [dcl.init]/7 で定義されています(C++11 では /6 で、この表現自体も同じ効果を持ちます)。
には デフォルト初期化 型のオブジェクトを
T
を意味します。
- もし
T
が (cv で修飾された) クラス型である場合 (条項 9)、そのデフォルトコンストラクタ (12.1) はT
が呼び出されます(そして,初期化 が不正確な場合T
がデフォルトコンストラクタやオーバーロードの解決を持たない場合 (13.3) の結果、曖昧になったり、削除された関数や 初期化のコンテキストからアクセスできない)。- もし
T
が配列型である場合、各要素は デフォルトで初期化される ;- を指定しない場合は、初期化を行いません。
このように
-
new A
単独で原因A
のデフォルトコンストラクタが呼び出されるだけで、そのコンストラクタが初期化されるわけではありません。m
. 不定値です。のはずです。new B
. -
new A()
は[dcl.init]/11(C++11では/10)に従って解釈されます。イニシャライザーが括弧の空集合であるオブジェクト、すなわち
()
であるオブジェクトは,値で初期化されなければならない。そして、次に [dcl.init]/8 (C++11† では /7) を考えてみましょう。
には 値初期化 型のオブジェクトを
T
を意味します。-
もし
T
が (cv-qualified) クラス型 (条項 9) で、デフォルトコンストラクタがない (12.1) か、デフォルトコンストラクタがユーザによって提供されるか削除されるかのいずれかである場合、オブジェクトはデフォルト初期化されます。 である場合、そのオブジェクトはデフォルトで初期化されます。 -
もし
T
が (おそらく cv-qualified) クラス型で、ユーザが用意した、あるいは削除されたデフォルトコンストラクタがない場合、そのオブジェクトは ゼロ初期化され、デフォルト初期化のためのセマンティック制約がチェックされます。 デフォルト初期化に関するセマンティック制約がチェックされ,T が自明でないデフォルトコンストラクタを持つ場合,オブジェクトはデフォルト初期化されます. コンストラクタがある場合、オブジェクトはデフォルト初期化されます。 -
もし
T
が配列型である場合、各要素は値で初期化されます。 - でない場合は、オブジェクトはゼロ初期化されます。
したがって
new A()
はゼロ初期化されます。m
. そして、これは次のように等価であるべきです。A
とB
. -
もし
-
new C
そしてnew C()
はオブジェクトを再びデフォルトで初期化します。なぜなら、最後の引用文の最初の箇条書きが適用されるからです (C にはユーザが提供するデフォルトのコンストラクタがあります!)。しかし、明らかに、今m
はどちらの場合もコンストラクタで初期化されます。
この段落は C++11 で若干異なる表現になっていますが、結果は変わりません。
には 値初期化 型のオブジェクトを
T
を意味します。
- もし
T
が (おそらく cv-qualified) クラス型 (条項 9) であり、ユーザが提供するコンストラクタ (12.1) がある場合。 ユーザが提供するコンストラクタ (12.1) がある場合、デフォルトのコンストラクタはT
のデフォルトコンストラクタが呼び出されます (そして、T がアクセス可能なデフォルトコンストラクタを持たない場合、初期化は不正な形式となります)。 のデフォルトコンストラクタがない場合、初期化は不正確です)。- もし
T
が (cv で修飾された) 非ユニオン型であり、ユーザが提供するコンストラクタがない場合 クラスであり、ユーザが提供するコンストラクタがない場合、オブジェクトはゼロ初期化されます。 ゼロ初期化され、もしT
の暗黙のうちに宣言されたデフォルトコンストラクタが自明でない場合、そのオブジェクトはゼロ初期化されます。 が自明でない場合、そのコンストラクタが呼び出されます。- もし
T
が配列型である場合。 の場合、各要素は値で初期化されます。- それ以外の場合、オブジェクトは ゼロ初期化されます。
関連
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] C++ ゼロ初期化 - なぜこのプログラムでは `b` は初期化されないのに `a` は初期化されるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] C++のPOD型とは何ですか?
-
[解決済み] 型名の後の括弧は、newで違いがあるのでしょうか?