¿Por qué un miembro de const podría inicializarse dos veces?


A continuación se muestra un fragmento de código que se puede compilar y ejecutar sin error en 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;
}

La salida es 555. Pero por lo que sé,const el objeto debe inicializarse solo una vez,después de lo cual el valor no es modificable.

Author: songyuanyao, 2018-05-03

2 answers

No se inicializa dos veces; el inicializador de miembros predeterminado simplemente se ignora. Así que para A a(555);, a.k se inicializa como 555.

Si un miembro tiene un inicializador de miembros predeterminado y también aparece en la lista de inicialización de miembros en un constructor, el inicializador de miembros predeterminado se ignora.

Del estándar, [clase.basar.init]/10:

Si un miembro de datos no estático dado tiene un miembro predeterminado inicializador y un mem-initializer, la inicialización especificada por el mem-inicializador se realiza, y el miembro de datos no estáticos por defecto se ignora el inicializador de miembros. [ Ejemplo: Dado

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

El constructor A (int) simplemente inicializará i al valor de arg, y los efectos secundarios en el inicializador de miembros predeterminado de i no tomarán lugar. - ejemplo final]

Por otro lado, dado

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;
};

Entonces para A a;, a.k se inicializará como 666.

 64
Author: songyuanyao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-04 02:57:33

Se inicializa solo una vez.

const int k = 666;

Se usaría si no se proporciona en constructor.

 8
Author: Jarod42,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-03 10:26:00