名前空間
変種
操作

値初期化

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

これは、空の初期化子でオブジェクトが構築されたときに実行される初期化です。

目次

[編集] 構文

T () (1)
new T () (2)
Class::Class(...) : member () { ... } (3)
T object {}; (4) (C++11以降)
T {} (5) (C++11以降)
new T {} (6) (C++11以降)
Class::Class(...) : member {} { ... } (7) (C++11以降)

[編集] 説明

値初期化は、これらの状況で実行されます。

1,5) 空の丸括弧の初期化子で名前のない一時オブジェクトが作成されるときまたは波括弧(C++11以降)
2,6) 空の丸括弧の初期化子を持つnew式によって動的記憶域期間を持つオブジェクトが作成されるときまたは波括弧(C++11以降)
3,7) 非静的データメンバーまたは基底クラスが、空の丸括弧のメンバー初期化子で初期化されるときまたは波括弧(C++11以降)
4) 名前付きオブジェクト(自動、静的、またはスレッドローカル)が波括弧のペアの初期化子で宣言されるとき。

すべてのケースで、空の波括弧 `{}` が使用され、`T` が集約型である場合、値初期化の代わりに集約初期化が実行されます。

もし`T`がデフォルトコンストラクタを持たないが、std::initializer_listを取るコンストラクタを持つクラス型である場合、リスト初期化が実行されます。

(C++11以降)

値初期化の効果は以下の通りです。

  • もし`T`が(cv修飾されている可能性のある)クラス型の場合
  • それ以外の場合、もし`T`が配列型であれば、配列の各要素は値初期化されます。
  • それ以外の場合、オブジェクトはゼロ初期化されます。

[編集] 注意

構文 T object(); はオブジェクトを初期化しません。引数なしで`T`を返す関数を宣言します。C++11より前に名前付き変数を値初期化する方法は、T object = T(); でしたが、これは一時オブジェクトを値初期化し、その後オブジェクトをコピー初期化します。ほとんどのコンパイラはこの場合コピーを省略します

参照は値初期化できません。

関数形式キャストで説明されているように、構文 T() (1) は、`T`が配列型を名前とする場合は禁止されていますが、T{} (5) は許可されています。

すべての標準コンテナ(std::vectorstd::listなど)は、単一の`size_type`引数で構築されるとき、または`resize()`の呼び出しによって拡張されるときに、アロケータが`construct`の動作をカスタマイズしない限り、要素を値初期化します。

[編集]

#include <cassert>
#include <iostream>
#include <string>
#include <vector>
 
struct T1
{
    int mem1;
    std::string mem2;
    virtual void foo() {} // make sure T1 is not an aggregate
}; // implicit default constructor
 
struct T2
{
    int mem1;
    std::string mem2;
    T2(const T2&) {} // user-provided copy constructor
};                   // no default constructor
 
struct T3
{
    int mem1;
    std::string mem2;
    T3() {} // user-provided default constructor
};
 
std::string s{}; // class => default-initialization, the value is ""
 
int main()
{
    int n{};                // scalar => zero-initialization, the value is 0
    assert(n == 0);
    double f = double();    // scalar => zero-initialization, the value is 0.0
    assert(f == 0.0);
    int* a = new int[10](); // array => value-initialization of each element
    assert(a[9] == 0);      //          the value of each element is 0
    T1 t1{};                // class with implicit default constructor =>
    assert(t1.mem1 == 0);   //     t1.mem1 is zero-initialized, the value is 0
    assert(t1.mem2 == "");  //     t1.mem2 is default-initialized, the value is ""
//  T2 t2{};                // error: class with no default constructor
    T3 t3{};                // class with user-provided default constructor =>
    std::cout << t3.mem1;   //     t3.mem1 is default-initialized to indeterminate value
    assert(t3.mem2 == "");  //     t3.mem2 is default-initialized, the value is ""
    std::vector<int> v(3);  // value-initialization of each element
    assert(v[2] == 0);      // the value of each element is 0
    std::cout << '\n';
    delete[] a;
}

実行結果の例

42

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 178 C++98 値初期化は存在しませんでした。空の初期化子はデフォルト初期化を呼び出します。
(`new T()`もゼロ初期化を実行しましたが)
空の初期化子は
値初期化を呼び出します。
CWG 543 C++98 ユーザー提供のコンストラクタがないクラスオブジェクトの値初期化は、
各サブオブジェクトの値初期化と同等でした
(ユーザー提供のデフォルトコンストラクタを持つメンバーをゼロ初期化する必要はありませんでした)
オブジェクト全体を
ゼロ初期化し、
その後
呼び出します。
デフォルトコンストラクタ
CWG 1301 C++11 削除されたデフォルトコンストラクタを持つ共用体の値初期化は、ゼロ初期化につながりました。
CWG 1368
現在は
デフォルト初期化
ユーザー提供のコンストラクタがあると C++98 ゼロ初期化がスキップされました
ユーザー提供のコンストラクタのみが
ゼロ初期化を
デフォルトコンストラクタ
スキップします。
CWG 1502 C++11 ユーザー提供のデフォルトコンストラクタを持たない共用体の値初期化は、
オブジェクトをゼロ初期化するだけでした。デフォルトメンバー初期化子
にもかかわらず
デフォルト初期化を
実行します。
ゼロ初期化の後
CWG 1507 C++98 ユーザー提供のコンストラクタがないクラスオブジェクトの値初期化は、
ユーザー提供のコンストラクタは、
無害なデフォルトコンストラクタの有効性をチェックしませんでした
無害なコンストラクタの
デフォルトコンストラクタ
有効性がチェックされます。
CWG 2820 C++98 ゼロ初期化に続くデフォルト初期化は、
非無害なコンストラクタを必要としました。
要求されない
CWG 2859 C++98 クラスオブジェクトの値初期化は、
デフォルト初期化が
実際にユーザー提供のコンストラクタを選択しない場合でも
ゼロ初期化を含む場合があります。
ゼロ初期化の後
この場合に

[編集] 関連項目

English 日本語 中文(简体) 中文(繁體)