[C++] Was ist die Membervariablenliste nach dem Doppelpunkt in einem Konstruktor?



Answers

Du bist ziemlich nah dran. Die erste Zeile ist die Deklaration. Das Label links von dem :: ist der Klassenname und um ein Konstruktor zu sein, muss der Funktionsname mit dem Klassennamen übereinstimmen.

TransparentObject::TransparentObject( int w, int x, int y, int z )

In C ++ können Sie optional einen Doppelpunkt und einige Initialwerte für Elementvariablen vor dem Anfang des Funktionskörpers setzen. Diese Technik muss verwendet werden, wenn Sie Const-Variablen initialisieren oder Parameter an einen Superklassenkonstruktor übergeben.

: 
 _someMethod( 0 ),
 _someOtherMethod( 0 ),
 _someOtherOtherMethod( 0 ),
 _someMethodX( 0 )

Und dann kommt der Rumpf des Konstruktors in geschweiften Klammern.

{
   int bla;
   int bla;
}
Question

Ich lese diesen C ++ - Quellcode und kam zu einem Konstruktor, aber ich verstehe es nicht (im Grunde, weil ich C ++ nicht weiß: P)

Ich verstehe C und Java sehr gut.

 TransparentObject::TransparentObject( int w, int x, int y, int z ) : 
     _someMethod( 0 ),
     _someOtherMethod( 0 ),
     _someOtherOtherMethod( 0 ),
     _someMethodX( 0 ) 
  {
       int bla;
       int bla;
  }

Soweit kann ich "ableiten" Die erste Zeile erklärt nur den Konstruktornamen, der "::" klingt wie "gehört zu" zu mir. Und der Code zwischen {} ist der Konstruktor selbst.

Ich "denke", was nach den Parametern und den ersten "{" ist wie Methoden Standardparameter oder etwas, aber ich finde keine vernünftige Erklärung im Internet. Die meisten C ++ - Konstruktoren, die ich in den Beispielen gefunden habe, sind fast identisch mit denen in Java.

Ich bin ich richtig in meinen Annahmen? "::" ist wie gehört zu, und die Liste nach Parametern und Körper sind wie "Standardargumente" oder etwas?

UPDATE: Danke für die Antworten. Mögen diese Methoden genannt werden? (Ich denke nein) und was ist der Unterschied, sie im Konstruktorkörper zu nennen




Ohne die Initialisiererliste zu verwenden, wird bei allen Klassenmitgliedern einfach der Standardkonstruktor aufgerufen. Dies ist der einzige Ort, an dem Sie kontrollieren können, welcher Konstruktor aufgerufen wird (für nicht dynamisch zugewiesene Member). Dasselbe gilt für den übergeordneten Klassenkonstruktor, der aufgerufen wird.

Klassenmitglieder, die im Körper des Konstruktors "initialisiert" wurden (dh zwischen den geschweiften Klammern mit dem Operator =), sind keine technische Initialisierung, sondern eine Zuweisung. Für Klassen mit einem nicht-trivialen Konstruktor / Destruktor kann es teuer sein, auf diese Weise Standardkonstrukte zu erstellen und dann durch Zuweisung zu modifizieren. Für Referenzmitglieder müssen Sie die Initialisiererliste verwenden, da sie nicht über den Zuweisungsoperator geändert werden können.

Wenn das Mitglied (oder die Elternklasse) keinen Standardkonstruktor hat, dann wird der Compiler einen Fehler erzeugen, wenn er in der Initialisierungsliste keinen geeigneten Konstruktor angibt. Andernfalls fügt der Compiler die Standardkonstruktoraufrufe selbst ein. Für eingebaute Typen tut dies nichts, also haben Sie Müllwerte dort.

Beachten Sie, dass die Reihenfolge, in der Sie die Elemente in der Initialisierungsliste angeben, sich nicht auf die Reihenfolge auswirkt, in der sie aufgerufen werden . Es ist immer zuerst der Elternklassenkonstruktor (falls vorhanden), dann die Klassenmitglieder in der Reihenfolge, in der sie in der Klassendefinition definiert sind. Die Reihenfolge, in der Sie sie in die Initialisiererliste eintragen, spielt keine Rolle und kann die Ursache für kleine Fehler sein ...

Im unten dargestellten Beispiel sieht es so aus, als würde m_b mit value initialisiert value dann m_a mit m_b , aber was tatsächlich passiert, ist, dass m_a mit m_b initialisiert m_b (was selbst noch nicht initialisiert ist), dann wird m_b mit value initialisiert. m_b enthält nur Müll!

struct BadInitialiserListExample
{
    BadInitialiserListExample(int value) :
        m_b(value),
        m_a(m_b)      // <-- *BUG* this is actually executed first due to ordering below!
    {
    }

    int    m_a;
    int    m_b;
};



Du hast Recht. Es ist eine Möglichkeit, die Standardwerte für die Klassenvariablen festzulegen. Ich kenne den genauen Unterschied zwischen ihnen nicht genau: und im Funktionskörper.




Ja, :: ist der C ++ - Scoping-Operator, mit dem Sie dem Compiler mitteilen können, zu welcher Funktion die Funktion gehört. Mit a: Nach der Konstruktor-Deklaration startet eine so genannte Initialisierungsliste.




Links