Почему const-член может быть инициализирован дважды? - PullRequest
0 голосов
/ 03 мая 2018

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

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

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

const int k = 666;

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

0 голосов
/ 03 мая 2018

Не инициализируется дважды; инициализатор члена по умолчанию просто игнорируется. Таким образом, для A a(555);, a.k инициализируется как 555.

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

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

Если данный нестатический элемент данных имеет оба элемента по умолчанию инициализатор и mem-инициализатор, инициализация, указанная 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.k будет инициализировано как 666.

...