Forum: PC-Programmierung c++ class constructor initializer list


von Vlad T. (vlad_tepesch)


Lesenswert?

Hi,
Eine Frage an alle c++-Standard-Auswendig-Kenner:

Ist es definiert in welcher Reihenfolge die Initializer abgearbeitet 
werden?

im VS2005 scheint es die Definitionsreihenfolge der Member zu sein, also 
unabhängig von der Reihenfolge in der Initializerliste.

Kann man sich darauf verlassen?

Hab grad mal folgendes Beispiel konstruiert.
1
class InitTesterData{
2
public:
3
  InitTesterData()
4
    :m(-1)
5
  {
6
    std::cout << "InitTesterData default"<<std::endl;
7
  }
8
  InitTesterData(int i, int m)
9
    :m(m)
10
  {
11
    std::cout << "InitTesterData "<<i<<": " << m<<std::endl;
12
  }
13
  int get(){return m;};
14
  int m;
15
};
16
17
class InitTester
18
{
19
public:
20
  InitTester()
21
    : m9(9,9)
22
    , m1(1,1)
23
    , m2(2,m5.get())
24
    , m4(4,4)
25
    , m6(6,6)
26
    , m5(5,5)
27
    , m7(7,m4.get())
28
    , m8(8,m9.get())
29
  {
30
  }
31
32
  InitTesterData m0;
33
  InitTesterData m1;
34
  InitTesterData m2;
35
  InitTesterData m3;
36
  InitTesterData m4;
37
  InitTesterData m5;
38
  InitTesterData m6;
39
  InitTesterData m7;
40
  InitTesterData m8;
41
  InitTesterData m9;
42
43
};
44
45
int main(int argc, char* argv[])
46
{
47
  InitTester inittester;
48
  return 0;
49
}

Output:
1
InitTesterData default
2
InitTesterData 1: 1
3
InitTesterData 2: -858993460
4
InitTesterData default
5
InitTesterData 4: 4
6
InitTesterData 5: 5
7
InitTesterData 6: 6
8
InitTesterData 7: 4
9
InitTesterData 8: -858993460
10
InitTesterData 9: 9

Hintergrund ist, dass ich sowas ähnliches imn Codereview gefunden habe 
und mir nicht sicher bin, ob man das nicht lieber lassen sollte oder ob 
man auf eine bestimmte Reihenfolge vertrauen kann.

Danke
Vlad

von Peter II (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> Ist es definiert in welcher Reihenfolge die Initializer abgearbeitet
> werden?

ich glaube ja.

> im VS2005 scheint es die Definitionsreihenfolge der Member zu sein, also
> unabhängig von der Reihenfolge in der Initializerliste.

teste mal mit dem GCC dort habe ich mal eine Warnung bekommen wenn die 
Reihenfolge nicht identisch war. Aus dem Grund glaube ich das es da eine 
festlegung gibt.

von Vlad T. (vlad_tepesch)


Lesenswert?

Peter II schrieb:
> teste mal mit dem GCC dort habe ich mal eine Warnung bekommen wenn die
> Reihenfolge nicht identisch war. Aus dem Grund glaube ich das es da eine
> festlegung gibt.

hab leider grad nix anderes zur Hand als das VS.

Eine Warnung wär auf jeden Fall sinnvol, wenn man auf Obekte zugreift, 
von denen der Compiler weiß, dass er sie später erst konstruieren wird.

von Tom K. (ez81)


Lesenswert?

Gegen Ende der ersten Antwort in 
http://msdn.microsoft.com/en-us/magazine/cc301399.aspx
"C++ initializes class members in the order they are declared, not the 
order they appear in the initializer list."

Das hat mich mal einen Nachmittag voller seltsamer Abstürze gekostet, 
als der Konstruktor eines Members eine Referenz auf einen anderen Member 
brauchte.

von Karl H. (kbuchegg)


Lesenswert?

Vlad Tepesch schrieb:

> Ist es definiert in welcher Reihenfolge die Initializer abgearbeitet
> werden?

Ja ist es.

>
> im VS2005 scheint es die Definitionsreihenfolge der Member zu sein, also
> unabhängig von der Reihenfolge in der Initializerliste.

genau so ist es definiert.

>
> Kann man sich darauf verlassen?

Ja

Warum ist das so?
Weil du mehrere Konstruktoren haben kannst, in denen kein Mensch 
sicherstellen kann, dass sie die gleiche Reihenfolge der 
Mwemberinitialisierungen besitzen (können ja in verschiedenen cpp-Files 
sein).
Warum ist das aber wiederrum wichtig?
Weil im Destruktor in genau der umgekehrten Reihenfolge wieder alles 
zerstört werden muss.

Die einzige 'Konstante', die du nicht willkürlich mal so oder mal so 
machen kannst, ist die Reihenfolge in der Klassendeklaration. Daher gilt 
die als die Reihenfolge in der Member constructed/destructed werden.

von Vlad T. (vlad_tepesch)


Lesenswert?

danke für die ausführliche Erklärung

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.