code_Kommentar
-
Das Tückische ist übrigens die Initialisier-Reihenfolge, aber nur wenn man nicht weiss wonach sie sich richtet. Hier ein Beispiel:
#include <iostream> using namespace std; class bar { public: bar(const char *s) { cout << s << " "; } }; class foo { public: foo() : m_a("was"), m_b("soll"), m_c("das") {} //Das Folgende würde gar nicht funktionieren, denn bar hat keinen Parameterlosen Konstruktor. //Dieser wird aber benötigt, weil die Member schon initialisiert werden, bevor der Code innerhalb //der Mengenklammern beginnt. Das heisst, wenn es einen Default-Konstruktor gäbe, würden die Member, //im Konstruktor-Block zum zweiten Mal initialisiert werden. Es sei denn der Compiler würde //den Unsinn erkennen und optimieren. //foo() //{ // m_a = bar("was"); // m_b = bar("soll"); // m_c = bar("das"); //} private: bar m_c,m_b,m_a; }; int main() { foo f; cout << endl; cin.get(); }
-
nillable schrieb:
Das Tückische ist übrigens die Initialisier-Reihenfolge, aber nur wenn man nicht weiss wonach sie sich richtet.
Moderne Compiler machen sowieso drauf aufmerksam, wenn die Reihenfolge nicht ok ist
-
Blue-Tiger schrieb:
Moderne Compiler machen sowieso drauf aufmerksam, wenn die Reihenfolge nicht ok ist
Inwiefern und welche? Beim Übersetzen des Beispiels macht weder g++ 3.4.2 (MinGW) noch VC 7.1 auf irgendwas aufmerksam.
Falls wir aneinander vorbeireden: das Tückische, das veranschaulicht werden sollte, ist, dass die Member nicht in der Reihenfolge initialisiert werden, in der man sie in der Initialisierungsliste aufführt, sondern in der Reihenfolge der Deklarationen.
-
=====> Bei elementaren Datentypen ist es *scheiss egal* was man macht, denn diese werden lokal nicht mit Standardwerten gefüllt. Bei Klassen jedoch sollte man es unbedingt machen da man ansonsten ein Konstruktoraufruf mehr hat.
-
FireFlow schrieb:
=====> Bei elementaren Datentypen ist es *scheiss egal* was man macht, denn diese werden lokal nicht mit Standardwerten gefüllt.
Es sei denn, man hat, wie otze schon andeutete, konstante Member.
-
FireFlow schrieb:
Bei elementaren Datentypen ist es *scheiss egal* was man macht
Eben nicht. Lies dir otze's Beitrag nachmal durch.
Oder wie siehts zB mit Referenzen aus?
-
groovemaster schrieb:
FireFlow schrieb:
Bei elementaren Datentypen ist es *scheiss egal* was man macht
Eben nicht. Lies dir otze's Beitrag nachmal durch.
Oder wie siehts zB mit Referenzen aus?
Ich meinte das ganz normale int var; Bei Referenken und const Typen siehts wieder anderst das stimmt.
-
na da hab ich ja was angerichtet!
Aber warum sie eben tükscih ist wurde ja schon gesagt....!
-
nillable schrieb:
Blue-Tiger schrieb:
Moderne Compiler machen sowieso drauf aufmerksam, wenn die Reihenfolge nicht ok ist
Inwiefern und welche? Beim Übersetzen des Beispiels macht weder g++ 3.4.2 (MinGW) noch VC 7.1 auf irgendwas aufmerksam.
...Nun, mein gcc macht mich darauf aufmerksam.
mfg
v R
-
virtuell Realisticer schrieb:
Nun, mein gcc macht mich darauf aufmerksam.
Du hast Recht. Dev-C++ 4.9.9.2 compiliert natürlich nicht per default mit -Wall. Dies habe ich erstmal über Kommandozeile ausprobiert, und siehe da:
g++ 3.4.2 schrieb:
main.cpp: In constructor
foo::foo()': main.cpp:20: warning:
foo::m_a' will be initialized after
main.cpp:20: warning:bar foo::m_b' main.cpp:17: warning: when initialized here main.cpp:20: warning:
foo::m_b' will be initialized after
main.cpp:20: warning: `bar foo::m_c'
main.cpp:17: warning: when initialized hereAnschließend habe ich im Dev-C++ im Menu Werkzeuge->Compiler Optionen im Reiter Compiler "Folgende Befehle beim Compiler-Aufruf hinzufügen:" aktiviert und dort -Wall eingetragen, so dass immer mit dieser Option compiliert wird.
Vielen Dank für diesen Hinweis, virtuell Realisticer!Beim VC++ 7.1 hingegen gibt es auch beim höchsten Warning Level /W4 diesbezüglich keinerlei Warnungen.
Ein Hoch auf g++!