c++ - überschriften - sätze mit doppelpunkt beispiele




Was macht ein Doppelpunkt, der einem C++-Konstruktornamen folgt? (6)

Diese Frage hat hier bereits eine Antwort:

Was macht der Doppelpunktoperator (":") in diesem Konstruktor? Entspricht MyClass(m_classID = -1, m_userdata = 0); ?

class MyClass {
public:

    MyClass() : m_classID(-1), m_userdata(0) { 
    }

    int m_classID;
    void *m_userdata;
};

Dies ist eine Initialisierungsliste und ist Teil der Implementierung des Konstruktors.

Die Unterschrift des Konstruktors lautet:

MyClass();

Dies bedeutet, dass der Konstruktor ohne Parameter aufgerufen werden kann. Dies macht es zu einem Standardkonstruktor , dh zu einem, der standardmäßig aufgerufen wird, wenn Sie MyClass someObject; schreiben MyClass someObject; .

Der Teil : m_classID(-1), m_userdata(0) heißt Initialisierungsliste . Es ist eine Möglichkeit, einige Felder Ihres Objekts (alle, wenn Sie möchten) mit Werten Ihrer Wahl zu initialisieren, anstatt sie als undefiniert zu belassen.

Nach dem Ausführen der Initialisierungsliste wird der Konstruktorhauptteil (der in Ihrem Beispiel leer ist) ausgeführt. Darin könnten Sie mehr Zuweisungen machen, aber sobald Sie es eingegeben haben, wurden alle Felder bereits initialisiert - entweder zu zufälligen, nicht spezifizierten Werten oder zu denen, die Sie in Ihrer Initialisierungsliste ausgewählt haben. Das bedeutet, dass die Zuweisungen, die Sie im Konstruktorhauptteil vornehmen, keine Initialisierungen, sondern Änderungen von Werten sind.


Dies wird als Elementinitialisierungsliste bezeichnet . Es wird verwendet, um die Konstruktoren der Superklasse aufzurufen, und gibt Ihren Membervariablen zum Zeitpunkt ihrer Erstellung einen Anfangswert.

In diesem Fall initialisiert es m_classID auf -1 und m_userData auf NULL.

Es ist nicht ganz gleichbedeutend mit der Zuweisung im Rumpf des Konstruktors, da dieser zuerst die Elementvariablen erstellt und ihnen dann zuordnet. Bei der Initialisierung wird der Anfangswert zum Zeitpunkt der Erstellung bereitgestellt, sodass er bei komplexen Objekten effizienter sein kann.


Es ist eine Initialisierungsliste . In Ihrem Beispiel ist es eher so (etwas ähnliches - bedeutet nicht, dass es in allen Fällen gleichwertig ist):


class MyClass {

public:

    MyClass(){
         m_classID = -1;
         m_userdata = 0;
    }

    int m_classID;
    void *m_userdata;

};

Es ist eine Initialisierungsliste.

Zu dem Zeitpunkt, an dem Sie in den Hauptteil des Konstruktors gelangen, sind alle Felder bereits konstruiert. Wenn sie Standardkonstruktoren haben, wurden diese bereits aufgerufen. Wenn Sie ihnen nun im Rumpf des Konstruktors einen Wert zuweisen, rufen Sie den Kopierzuweisungsoperator auf, was bedeuten kann, Ressourcen (z. B. Speicher) freizugeben und wiederzuerlangen, wenn das Objekt eines besitzt.

Im Fall von primitiven Typen wie int gibt es also keinen Vorteil, wenn man sie im Rumpf des Konstruktors zuordnet. Bei Objekten mit einem Konstruktor handelt es sich um eine Leistungsoptimierung, da zwei Objektinitialisierungen anstelle von einem vermieden werden.

Eine Initialisierungsliste ist erforderlich, wenn eines der Felder eine Referenz ist, da eine Referenz niemals null sein kann, auch nicht in der kurzen Zeit zwischen der Objektkonstruktion und dem Rumpf des Konstruktors. Das folgende löst Fehler C2758: "MyClass :: member_": muss in Konstruktor Base / Member Initializer-Liste initialisiert werden

class MyClass {
public :
    MyClass(std::string& arg) {
        member_ = arg;
    }
    std::string& member_;
};

Der einzig richtige Weg ist:

class MyClass {
public :
    MyClass(std::string& arg) 
        : member_(arg) 
    {
    }
    std::string& member_;
};

Es kennzeichnet den Anfang einer Initialisierungsliste, die zum Initialisieren von Elementvariablen Ihres Objekts dient.

Was: MyClass(m_classID = -1, m_userdata = 0);

Das deklariert einen Konstruktor, der Argumente annehmen kann (also könnte ich eine MyClass mit MyClass m = MyClass(3, 4) erstellen, was dazu führen würde, dass m_classID 3 ist und m_userdata 4). Wenn ich dem MyClass Konstruktor keine Argumente übergeben würde, würde dies dazu führen, dass ein gleichwertiges Objekt für die Version mit der Initialisiererliste erstellt wird.


Es signalisiert den Beginn einer Initialisierungsliste.

Außerdem entspricht es nicht MyClass (m_classId = -1, m_userData = 0). Dies versucht einen Konstruktor mit 2 Parametern zu definieren, die Standardwerte haben. Die Werte fehlen jedoch und sollten nicht kompiliert werden.





ctor-initializer