Initialiserungsliste
-
Ja, aber bis die dann im Konstruktor zugewiesen werden vergehen ja nur Millisekunden.
Ich habe halt gelesen, dass man das machen MUSS?!
-
blub85 schrieb:
Ich habe halt gelesen, dass man das machen MUSS?!
Ja, fuer Referenzen und const Member MUSS man die Initialization List nehmen.
-
@blub85
Ohne Initializer-Liste ist vergleichbar mitvoid EineFunktion() { VariablenTyp variable; variable = irgendwas; // ... }Mit Initializer-Liste ist vergleichbar mit
void EineFunktion() { VariablenTyp variable(irgendwas); // ... }Was cooky451 meint:
class Foo { public: Foo() // nix hier { WarteEineHalbeStunde(); m_var = 123; } private: int m_var; };m_var wird "un-initialisiert" erzeugt.
Dann warten wir ne halbe Stunde. In der Zeit wird m_var aber nicht gelesen.
Kann gar nicht, kennt ja noch keiner die Adresse von m_var (WarteEineHalbeStunde() ist in diesem Beispiel keine Memberfunktion von Foo!).Das ist vollkommen OK.
Was dagegen nicht OK ist, ist sowas:
class Foo { public: Foo() // nix hier { int blossMalGucken = m_var; m_var = 123; } private: int m_var; };Das gibt undefiniertes Verhalten.
Und zwar weil m_var gelesen wird, bevor es initialisert wurde. Das darfst du laut Standard nicht.
Wie lange irgendwas dauert ist dabei vollkommen irrelevant.
-
Okay, danke für die Codebeispiele.
Allerdings habe ich gelesen, dass man das nur bei konstanten und Referenzmembern machen muss mit der Initialisierungsliste?!?
In dem Bsp. oben kommt ja keine konstante vor. Dennoch verstehe ich den potentiellen Fehler, der dadurch entstehen kann...
-
blub85 schrieb:
Allerdings habe ich gelesen, dass man das nur bei konstanten und Referenzmembern machen muss mit der Initialisierungsliste?!?
http://www.c-plusplus.net/forum/p2198453?highlight=basisklasse#2198453
-
@blub85
Was ist denn so schwer zu verstehen?
Du musst Zeugs erstmal schreiben bevor du es lesen darfst. WIE ist dabei ganz egal. Also Init-Liste ist gut, normale Zuweisung ist auch gut. Nur immer erst schreiben, dann darf man erst lesen.
-
Und im Normalfall würde ich die Initialisierungsliste den Zuweisungen vorziehen. Erstere reicht meist aus. Es sei denn, du hast gute Gründe, einzelne Member erst später zu initialisieren.
-
Nexus schrieb:
später zu initialisieren.
:p Da hast du nun einen Widerspruch in sich gebaut.
-
Gugelmoser schrieb:
Nexus schrieb:
später zu initialisieren.
:p Da hast du nun einen Widerspruch in sich gebaut.
Wo denn?
-
@Gugelmoser
Nene, das passt schon.
Bestimmte Typen (Integers, Floats, Zeiger) kann man "uninitialisiert" erzeugen.
Dann macht "später initialisieren" schon Sinn.
-
hustbaer schrieb:
@Gugelmoser
Nene, das passt schon.
Bestimmte Typen (Integers, Floats, Zeiger) kann man "uninitialisiert" erzeugen.
Dann macht "später initialisieren" schon Sinn.Wie meinst du das hustbar?
class foo { private: int i; public: foo() // Wenn i doch hier definiert wird... { // ...kann doch ab hier keine Initialisierung mehr stattfinden... i = 7; // ...sondern nur noch eine Zuweisung. } };Was versteht ihr also unter später initialisiern?
-
Gugelmoser schrieb:
class foo { private: int i; public: foo() // Wenn i doch hier definiert wird... { // ...kann doch ab hier keine Initialisierung mehr stattfinden... i = 7; // ...sondern nur noch eine Zuweisung. } };Was versteht ihr also unter später initialisiern?
Die Variable i ist nicht initialisiert, sie enthaelt einen undefinierten Wert, denn sie wurde nie initialisiert. Deswegen ist i = 7 eine Initialisierung.
-
icarus2 schrieb:
Gugelmoser schrieb:
class foo { private: int i; public: foo() // Wenn i doch hier definiert wird... { // ...kann doch ab hier keine Initialisierung mehr stattfinden... i = 7; // ...sondern nur noch eine Zuweisung. } };Was versteht ihr also unter später initialisiern?
Die Variable i ist nicht initialisiert, sie enthaelt einen undefinierten Wert, denn sie wurde nie initialisiert. Deswegen ist i = 7 eine Initialisierung.
Ok, dann verstehen wir was unterschiedliches unter Initialisierung. Für mich beinhaltet eine Initialisierung immer eine Definition... Folglich unterscheidest du nicht zwischen Initialisierung und Zuweisung, oder wie?
-
icarus2 schrieb:
Deswegen ist i = 7 eine Initialisierung.
i = 7 ist eine Zuweisung. Und zwar immer. Zugegeben: Bei einem simplen int macht das hier keinen wirklichen Unterschied, aber das ändert nix an der Terminologie.
-
Es ist sehr heikel unter welchen Umstaenden etwas initialisiert wird.
Zum Beispiel hier wird i nicht initialisiert:
class foo { public: int i; foo() { // x ist hier nicht initialisiert } }; int main() { foo f; cout << f.i << endl; }Ich habe vorher gegoogelt und keine genauen Informationen dazu gefunden. Scott Meyers meint mal soll einfach immer alle Variablen initialisieren, da die Regeln viel zu kompliziert seien.
-
Also so kompliziert sind die Regeln jetzt nicht...
-
dot schrieb:
Also so kompliziert sind die Regeln jetzt nicht...
Aber warum soll dann i = 7 immer eine Zuweisung sein? Vielleicht habe ich eine falsche Definition von Initialisierung im Kopf. Aber i = 7 ist doch eine Initialisierung weil der Variable i vorher noch kein Wert zugewisen wurde. Sie hat bloss uninitialisierten Speicher bekommen. Dann waere i = 7 doch eine Initialisierung?
-
Es gibt einen wesentlichen Unterschied zwischen Initialisierung und Zuweisung. Initialisieren bedeutet eben, dass das Objekt bereits mit einem bestimmten Wert erzeugt wird. Bei einer Zuweisung dagegen wird einem bereits erzeugten Objekt ein neuer Wert zugewiesen. Wenn du dir das jetzt immer nur anhand der Bits eines einzelnen int überlegst, wirkt es vielleicht so, als wär das alles irgendwie das Gleiche. Wenn du statt int aber mal einen beliebigen Typ nimmst, z.B. irgendeine Klasse, dann macht es einen riesen Unterschied. Eine Klasse könnte z.B. überhaupt nur Initialisierung, aber keine Zuweisung unterstützen...
-
Ich glaube ich verstehe was du meinst. Aber um sicher zu gehen:
int main() { int x = 0; // Definition mit Initialisierung int y; // Definition y = 0; // Zuweisung }Ist das korrekt? Stimmt es, dass eine Initialisierung nur zusammen mit einer Definition auftreten kann?
-
icarus2 schrieb:
Ist das korrekt?
Ja
icarus2 schrieb:
Stimmt es, dass eine Initialisierung nur zusammen mit einer Definition auftreten kann?
Nicht ganz. Bei einem Klassenmember erfolgt die Initialisierung in der Initialisierungsliste des Konstruktors. Aber bei lokalen Variablen ja.