[解決済み] C++ ゼロ初期化 - なぜこのプログラムでは `b` は初期化されないのに `a` は初期化されるのですか?
質問
の回答として認められている(そして唯一の)答えによると このStack Overflowの質問 ,
<ブロッククオートでコンストラクタを定義する。
MyTest() = default;
は、代わりにオブジェクトをゼロ初期化します。
ではなぜ以下のようになるのか。
#include <iostream>
struct foo {
foo() = default;
int a;
};
struct bar {
bar();
int b;
};
bar::bar() = default;
int main() {
foo a{};
bar b{};
std::cout << a.a << ' ' << b.b;
}
はこのような出力をします。
0 32766
定義されているコンストラクタはどちらもデフォルト?ですよね?そしてPOD型はデフォルトの初期化はゼロ初期化です。
そして、受け入れられた答えによると この質問 ,
POD メンバがコンストラクタでも C++11 のクラス内初期化でも初期化されない場合、デフォルトで初期化されます。 クラス内初期化でも初期化されない場合、デフォルトで初期化されます。
スタックやヒープに関係なく、答えは同じです。
C++98 (およびそれ以降) では、new int() はゼロ初期化を実行するように指定されていました。 ゼロ初期化を行うように指定されていました。
私の(とはいえ)ラップをしようとしたにもかかわらず 小さな を理解しようとしているにもかかわらず デフォルトコンストラクタ と デフォルトの初期化 の2つがありますが、説明を思いつきませんでした。
どのように解決するのですか?
ここでの問題は、かなり微妙です。 あなたは次のように考えるでしょう。
bar::bar() = default;
を使えば、コンパイラが生成したデフォルトのコンストラクタが得られると思いますし、実際そうなのですが、現在はユーザが提供したものとみなされています。 [dcl.fct.def.default]/5 の状態になります。
明示的にデフォルト化された関数と暗黙的に宣言された関数をまとめてデフォルト化関数と呼び、実装では暗黙的な定義([class.ctor] [class.dtor], [class.copy.ctor], [class.copy.assign] )を提供しなければならず、これは削除したものとして定義するということかもしれません。 関数は、ユーザが宣言し、最初の宣言で明示的にデフォルトまたは削除されていない場合、ユーザが提供するものです。 ユーザが提供した明示的にデフォルトされた関数(すなわち、最初の宣言の後に明示的にデフォルトされた関数)は、明示的にデフォルトされた時点で定義されます。そのような関数が暗黙的にdeletedとして定義されている場合、そのプログラムは不正確な形式となります。[ 注:関数を最初の宣言の後にdefaultedとして宣言することで、効率的な実行と簡潔な定義を実現しつつ、進化するコードベースに対して安定したバイナリインタフェースを実現することができる。- エンドノート ]。
強調
ということは、あなたがデフォルトの
bar()
をデフォルトにしなかったため、ユーザが提供したものとみなされます。 そのため
[dcl.init]/8.2
Tがユーザ提供または削除されたデフォルトコンストラクタを持たない(おそらくcv-qualified)クラス型の場合、オブジェクトはゼロ初期化され、デフォルト初期化のためのセマンティック制約がチェックされ、Tが自明ではないデフォルトコンストラクタを持つ場合、オブジェクトはデフォルト初期化されます。
はもはや適用されず、値の初期化も行われません。
b
で初期化するのではなく
[dcl.init]/8.1に従って初期化します。
Tが(おそらくcv-qualified)クラス型([class])で、デフォルトコンストラクタ([class.default.ctor])が無いか、デフォルトコンストラクタがユーザ提供または削除されている場合、そのオブジェクトはデフォルト初期化(default-initialized)となります。
関連
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】'cout'は型名ではない
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された
-
[解決済み] なぜリストの初期化(中括弧を使用)が他の方法より優れているのですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。