Почему член const может быть инициализирован дважды?

Ниже приведен фрагмент кода, который можно скомпилировать и запустить без ошибок в 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 объект должен быть инициализирован только один раз, после чего значение не поддается изменению.

Ответы

Ответ 1

Он не инициализируется дважды; инициализатор элемента по умолчанию просто игнорируется. Итак, для A a(555); , ak инициализируется как 555.

Если член имеет инициализатор элемента по умолчанию и также появляется в списке инициализации члена в конструкторе, инициализатор элемента по умолчанию игнорируется.

Из стандарта [class.base.init]/10:

Если данный нестатический член данных имеет как инициализатор элемента по умолчанию, так и инициализатор mem, инициализация, указанная mem-инициализатором, выполняется, а инициализатор элемента нестатического элемента данных игнорируется. [Пример: с учетом

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

конструктор A (int) будет просто инициализировать я до значения arg, а побочные эффекты в инициализаторе элемента по умолчанию я не будут иметь места. - конец примера]

С другой стороны, данный

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; , ak будет инициализирован как 666.

Ответ 2

Он инициализируется только один раз.

const int k = 666;

будет использоваться, если не предусмотрено в конструкторе.