Reihenfolge des Aufrufs des Basisklassenkonstruktors aus der Initialisierungsliste der abgeleiteten Klasse

8
%Vor%

Oben ist nur Pseudo-Code. Eigentlich wollte ich wissen, dass die Reihenfolge des Aufrufs des Basiskonstruktors von Bedeutung ist? Gibt es schlechte Verhaltensweisen (besonders Eckfälle ), die durch einen der Fälle verursacht werden? Meine Frage bezieht sich auf den technischen Aspekt und nicht auf Codierungsstile.

    
iammilind 06.06.2011, 03:51
quelle

3 Antworten

14

Die Reihenfolge, auf die Sie in Ihrer Frage verweisen, ist nicht die "Reihenfolge des Aufrufs des Basiskonstruktors". Tatsächlich können Sie keinen Konstruktor aufrufen. Konstruktoren können vom Benutzer nicht aufgerufen werden. Nur Compiler kann Konstruktoren aufrufen.

Sie können Initialisierer angeben . In diesem Fall (Konstruktorinitialisiererliste) geben Sie Initialisierer für Unterobjekte eines größeren Objekts an. Die Reihenfolge, in der Sie diese Initialisierer angeben, spielt keine Rolle: Der Compiler ruft die Konstruktoren in einer bestimmten Reihenfolge auf, die durch die Sprachspezifikation definiert ist, unabhängig von der Reihenfolge, in der Sie die Initialisierer angeben. Die Basisklassenkonstruktoren werden immer zuerst aufgerufen (in der Reihenfolge, in der die Basisklassen in der Klassendefinition aufgelistet sind). Dann werden die Konstruktoren der Teilunterobjekte aufgerufen (wiederum in der Reihenfolge, in der diese Elemente in der Klassendefinition aufgelistet sind).

(Es gibt einige Besonderheiten in dieser Regel, wenn es um virtuelle Basisklassen geht, aber ich habe beschlossen, sie hier nicht einzubeziehen.)

Was die schlechten Verhaltensweisen betrifft ... Natürlich gibt es hier ein Potenzial für "schlechtes Benehmen". Wenn Sie annehmen, dass die Reihenfolge der Initialisierung von der Reihenfolge abhängt, die Sie in der Konstruktorinitialisiererliste verwendet haben, werden Sie höchstwahrscheinlich zu einer unangenehmen Überraschung kommen, wenn Sie feststellen, dass der Compiler diese Reihenfolge vollständig ignoriert und eine eigene Reihenfolge verwendet Erklärung) statt. Zum Beispiel der Autor dieses Codes

%Vor%

könnte erwarten, dass a zuerst initialisiert wird und b den Anfangswert von 5 von a erhält, aber in Wirklichkeit wird dies nicht passieren, da b vor a initialisiert wird.

    
AnT 06.06.2011, 03:58
quelle
5

Die Reihenfolge ist gut definiert. Es hängt nicht davon ab, wie Sie sie bei der Initialisierung angeben.
Der Basisklassenkonstruktor B wird zuerst aufgerufen und dann die Mitgliedsvariablen ( d1 & amp; d2 ) in der Reihenfolge, in der sie deklariert sind.

Um den Kommentar in @Andrey T's Antwort zu erklären.

%Vor%

Die Reihenfolge des Aufrufs der Basisklassenkonstruktoren ist vom Standard gut definiert und lautet:

%Vor%

Die virtuelle Basisklasse MyClass3 wird gegenüber der Basisklasse MyClass2 bevorzugt.

    
Alok Save 06.06.2011 03:55
quelle
3

Die Reihenfolge der Dinge in der Initialisierungsliste ist nicht signifikant. In Ihrem Fall wird das Basisobjekt immer zuerst initialisiert, gefolgt von d1 und d2 in dieser Reihenfolge. Die Initialisierung wird in der Reihenfolge der Ableitung durchgeführt, und in der Reihenfolge erscheinen die Member in der Klassendefinition.

Nachdem dies gesagt wurde, wird es normalerweise als guter Stil angesehen, die Initialisierungsliste in der Reihenfolge der Initialisierung zu schreiben, und einige Compiler werden eine Warnung ausgeben, wenn Sie dies nicht tun.

    
Neil Butterworth 06.06.2011 03:55
quelle