Initialisierungsliste im Ctor
-
Abend,
sagen wir ich habe eine Klasse mit einigen Membern:
Class Foo { A a; B b; C c; D* d; };Im Ctor von Foo könnte ich einige Member in der Initialisierungsliste initialisieren, andere kann ich erst im Ctor Rumpf durch Berechnungen setzen. Also in etwa so:
Foo::Foo(B myB, int bla) : b(myB) { // Rechnungen a = compute(bla); c = computeNochwas(); }Meine Frage: Wenn ich nur MANCHE Member in einer Initialisierungsliste initialisieren kann, lass ich dann die Initialisierungsliste besser ganz weg? Oder ist es ok die Member die man sofort initialisieren kann in der Initialisierungsliste zu setzen und den Rest im Ctor-Rumpf?
-
Du darfst in den Initialisierungslisten durchaus rechnen, kein Problem.
Und selbst wenn dir Rechnung doch nicht in die Initialisierungsliste passen sollte: Welchen Vorteil versprichst du dir dadurch, die Initialisierungsliste nicht zu benutzen? Ich sehe bloß die üblichen Nachteile wie beim Nicht-Benutzen der Initialisierungsliste.
-
Naja, ich habe irgendwo mal gelesen, dass die Member in die Reihenfolge initialisiert werden in der sie in der Klassendefinition stehen und NICHT in der Reihenfolge der Initialisierungsliste (stimmt das?).
Irgendwie dachte ich, dass es vielleicht Nachteile gibt, wenn man nur einen Teil der Member in der Initialisierungsliste initialisiert und den anderen Rest im Rumpf.
-
DasWandelndeSchloss schrieb:
Naja, ich habe irgendwo mal gelesen, dass die Member in die Reihenfolge initialisiert werden in der sie in der Klassendefinition stehen und NICHT in der Reihenfolge der Initialisierungsliste (stimmt das?).
Ja.
Irgendwie dachte ich, dass es vielleicht Nachteile gibt, wenn man nur einen Teil der Member in der Initialisierungsliste initialisiert und den anderen Rest im Rumpf.
Ja, das gibt nämlich dann einen Nachteil, wenn Abhängigkeiten zwischen verschiedenen Membern bestehen (etwa bei besagter Rechnung). Besagter Nachteil ist, dass es dann nicht funktioniert
. Ich war jetzt davon ausgegangen, dass dieser (eher seltene) Fall bei dir nicht vorliegt.
-
Welche Vorteile hat die Initialisierungsliste noch,
abgesehen von der "Initialisierung" statt einer "Definition+Zuweisung" ?mfg dweb
-
Dweb schrieb:
Welche Vorteile hat die Initialisierungsliste noch,
abgesehen von der "Initialisierung" statt einer "Definition+Zuweisung" ?Du kannst Konstanten initialisieren und Konstruktoren von Basisklassen aufrufen.
-
Janjan schrieb:
Dweb schrieb:
Welche Vorteile hat die Initialisierungsliste noch,
abgesehen von der "Initialisierung" statt einer "Definition+Zuweisung" ?Du kannst Konstanten initialisieren und Konstruktoren von Basisklassen aufrufen.
ohh joa Konstruktoraufruf der Basisklasse

hmm Initialisierung von Konstanten und Referencen hätte ich jetzt eher unter "have-to" eingeordnet als unter "Vorteil" xD
-
Dweb schrieb:
ohh joa Konstruktoraufruf der Basisklasse

hmm Initialisierung von Konstanten und Referencen hätte ich jetzt eher unter "have-to" eingeordnet als unter "Vorteil" xD
Die Konstruktoren der Basisklasse kannst du auch nur in der Initialisierungsliste aufrufen. Also auch ein "have-to".
-
kann ich dir net widersprechen^^
-
Dweb schrieb:
Welche Vorteile hat die Initialisierungsliste noch,
abgesehen von der "Initialisierung" statt einer "Definition+Zuweisung" ?Konsistenz. Alles in der Initialisierungsliste, dann brauchst du keine Sonderbehandlung für Dinge, die dort stehen müssen und hast keine Nachteile bei optionalen Dingen. Ausnahmen wie verzögerte Initialisierung gibts natürlich trotzdem. Aber als Grundsatz empfiehlt es sich, so viel wie möglich in der Konstruktor-Initialisierungsliste zu initialisieren.
Wofür die Initialisierungsliste zwingend notwendig ist:
const-qualifizierte Membervariablen- Referenzen
- Member ohne Defaultkonstruktor
- Member, die den Zuweisungsoperator nicht unterstützen
- Basisklassen ohne Defaultkonstruktor
-
Member, die den Zuweisungsoperator nicht unterstützen
Nope. Nicht im geringsten. Also nicht zwingend.
-
Du hast Recht. Ich hätte ausdrücklich sagen sollen, dass ich mich auf den Vergleich von Zuweisungen im Konstruktorrumpf und Initialisierungen in der Initialisierungsliste beziehe.
Also "zwingend" im Sinne von "funktioniert nicht mit späteren Zuweisungen".
-
OK, wenn du explizit Zuweisung im Konstruktorrumpf schreibst, dann ja.

Ich dachte an Dinge wie CFile aus der MFC.
Kann default-konstruiert werden.
Kann nicht zugewiesen werden.
Kann dafür aber mit diversen Funktionen nachträglich "geändert" (bzw. allgmein verwendet) werden.z.B. mit Open() ein File aufmachen etc.
-
Initialisierungslisten werden schnell unleserlich, daher versuche ich sie grundsätzlich zu vermeiden.
-
einint schrieb:
Initialisierungslisten werden schnell unleserlich, daher versuche ich sie grundsätzlich zu vermeiden.
Inwiefern ist
MyClass::MyClass(int newInt, double newDouble, const std::string& newString) : myInt(newInt) , myDouble(newDouble) , myString(newString) { }unübersichtlicher als
MyClass::MyClass(int newInt, double newDouble, const std::string& newString) { myInt = newInt; myDouble = newDouble; myString = newString; }Und wie kann ich mir das vorstellen? Nimmst du die erwähnten Nachteile billigend in Kauf, nur der Syntax wegen?
Oder schlimmer, designst du Klassen sogar entsprechend? Also z.B. überall Defaultkonstruktoren bereitstellen, auch wenn diese unangebracht sind?