Frage

habe ich einige Zweifel über die Konstruktion und Initialisierungsreihenfolge Garantien in C ++. Zum Beispiel hat der folgenden Code vier Klassen X, Y, Z und W. Die Hauptfunktion instanziiert ein Objekt von class X, die ein Objekt von class Y enthält, und leitet daraus ab class Z, so werden beiden Konstruktoren aufgerufen werden. Darüber hinaus wird die const char* Parameter X Konstruktor übergeben implizit auf ein Objekt class W umgewandelt werden, so W Konstruktor muss auch genannt werden.

Was sind die Garantien der C ++ Standard auf die Kopierkonstruktoren auf der Reihenfolge der Anrufe gibt? Oder äquivalent, was dieses Programm erlaubt drucken?

#include <iostream>

class Z {
   public:
   Z() { std::cout << "Z" << std::endl; }
};

class Y {
   public:
   Y() { std::cout << "Y" << std::endl; }
};

class W {
   public:
   W(const char*) { std::cout << "W" << std::endl; }
};

class X : public Z {
   public:
   X(const W&) { std::cout << "X" << std::endl; }
   private:
   Y y;
};

int main(int, char*[]) {
   X x("x");
   return 0;
}

Bearbeiten: Ist das richtig

   W      |
 /   \    |
Z     Y   |
 \   /    |
   X      V
War es hilfreich?

Lösung

In allen Klassen wird Baubefehl garantiert: Basisklassen, von links nach rechts angegeben, gefolgt von Membervariablen in der Reihenfolge, in der Klassendefinition deklarierte. Eine Klasse Konstruktor Körper ausgeführt wird, sobald alle seine Basen und Mitglieder Konstruktionen abgeschlossen haben.

In Ihrem Beispiel X aus Z abgeleitet und enthält Y so die Z Basisobjekt zuerst aufgebaut ist, dann das Y Mitglied y, dann den Aufbau der X schließt mit der Ausführung von X Konstruktor Körper.

Die temporären W benötigt wird, um an den Konstruktor von X zu passieren, so dass es gebaut wird, bevor der Bau des x beginnt und sobald die Initialisierung von x abgeschlossen ist zerstört werden.

So muss das Programm gedruckt werden:

W
Z
Y
X

Andere Tipps

1) Zunächst einmal ist es notwendig, die Argumente zu berechnen.

2) Dann Basisklassen aufgebaut sind.

3) Dann Mitglieder in der Reihenfolge ihres Auftretens in der Deklaration der Klasse aufgebaut sind.

4) Dann Constructor von X heißt

  1. Das W-Objekt aufgebaut wird, bevor der Konstruktor X genannt wird.
  2. Z, als Basisklasse von X, wird vor den Mitgliedern von X initialisiert werden.
  3. wird Y während Memberinitialisierungsliste initialisiert werden
  4. X Konstruktor ausgeführt wird.

Um auf Charles Bailey Antwort zu erweitern, ändern sich die Regeln, wenn Ihre Basisklassen praktisch vererbt werden. Ich habe immer vergessen, was die Ordnung ist, sagt die IBM-Website, dass virtuelle Basen zunächst initialisiert werden, aber ich habe einfach nie in einen Fall ausgeführt, wo es eigentlich mehr als Nebensächlichkeiten.

Zusammengefasst sind dies die Regeln:

  1. Argumente, von rechts nach links
    genommen  ein. Rechts meisten
     b. 2.vr
  2. Basisklasse
  3. Virtuelle Basis
  4. Basisklassen von links nach rechts
  5. Mitglieder in der Reihenfolge der Deklaration in der Klasse
  6. Constructor der genannten Klasse
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top