c++ class constructor initializer list

#2243344
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
Gast #2243363
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.
#2243388
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.
#2244072
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren