wake-up-neo.com

Warum kann ein const-Member zweimal initialisiert werden?

Im Folgenden finden Sie einen Codeausschnitt, der in vs2015 kompiliert und fehlerfrei ausgeführt werden konnte

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

Die Ausgabe ist 555. Soweit ich weiß, sollte das Objekt const nur einmal initialisiert werden. Danach kann der Wert nicht mehr geändert werden.

38
bigxiao

Es wird nicht zweimal initialisiert. Der Standard-Member-Initialisierer wird einfach ignoriert. Also für A a(555);, a.k wird initialisiert als 555.

Wenn ein Member über einen Standard-Member-Initialisierer verfügt und in einem Konstruktor auch in der Member-Initialisierungsliste angezeigt wird, wird der Standard-Member-Initialisierer ignoriert.

Aus dem Standard [class.base.init]/1 :

Wenn ein bestimmtes nicht statisches Datenelement sowohl einen Standardelementinitialisierer als auch einen Mem-Initialisierer aufweist, wird die vom Mem-Initialisierer angegebene Initialisierung ausgeführt und der Standardelementinitialisierer des nicht statischen Datenelements wird ignoriert. [Beispiel: Gegeben

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

der Konstruktor A(int) initialisiert i einfach auf den Wert von arg, und die Nebeneffekte im Standard-Member-Initialisierer von i treten nicht auf. - end example]

Andererseits gegeben

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

dann für A a;, a.k wird initialisiert als 666.

64
songyuanyao

Es wird nur einmal initialisiert.

const int k = 666;

würde verwendet, wenn nicht im Konstruktor angegeben.

8
Jarod42