web-dev-qa-db-ja.com

constメンバーが2回初期化されるのはなぜですか?

以下は、vs2015でエラーなしでコンパイルおよび実行できるコードスニペットです。

#include<iostream>
using namespace std;

class A {
    public:
        A(int b) :k(b) {}//second time
    const int k = 666;//first time
};

int main() {
    A a(555);
    cout << a.k << endl;
    return 0;
}

出力は555。しかし、私の知る限り、constオブジェクトは一度だけ初期化する必要があり、その後は値は変更できません。

38
bigxiao

2回初期化されません。 デフォルトのメンバー初期化子 は無視されます。したがって、A a(555);の場合、a.k555として初期化されます。

メンバーにデフォルトのメンバー初期化子があり、コンストラクターのメンバー初期化リストにも表示されている場合、デフォルトのメンバー初期化子は無視されます。

標準から、 [class.base.init]/1

特定の非静的データメンバーにデフォルトメンバー初期化子とmem-initializerの両方がある場合、mem-initializerで指定された初期化が実行され、非静的データメンバーのデフォルトメンバー初期化子は無視されます。 [例:与えられた

struct A {
  int i = /* some integer expression with side effects */ ;
  A(int arg) : i(arg) { }
  // ...
};

A(int)コンストラクターは単にiをargの値に初期化し、iのデフォルトのメンバー初期化子の副作用は発生しません。

一方、与えられた

class A {
public:
    A() {}            // k will be initialized via default member initializer, i.e. 666
    A(int b) :k(b) {} // k will be initialized via member initializer list, i.e. b

    const int k = 666;
};

A a;の場合、a.k666として初期化されます。

64
songyuanyao

1回だけ初期化されます。

const int k = 666;

コンストラクタで提供されない場合に使用されます。

8
Jarod42