Ich weiß, dass in einer class
die Mitglieder in der Reihenfolge initialisiert werden, in der sie aufgeführt sind. Gilt das für die Gruppierung von Variablen in public
und private
usw.? Meine Verwirrung ist, dass ich nicht herausfinden konnte, ob es Präferenz wie private
Mitglieder in der Reihenfolge initialisiert werden, die sie vor public
Mitglieder unabhängig davon aufgeführt wurden, wo die privaten Variablen in Bezug auf die Öffentlichkeit in einer Klassendeklaration aufgeführt sind (ich kenne solche Voreingenommenheit existieren in Richtung der Basisklasse Mitglieder)C++ Klassenelement Initialisierungssequenz
Antwort
die Regeln für die Klasse der Initialisierung werden in [class.base.init]/11
in einem nicht zum Delegieren Konstruktor Initialisierung erfolgt in der folgenden Reihenfolge buchstabiert:
Zuerst und nur für den Konstruktor der am weitesten abgeleiteten Klasse (1.8) werden virtuelle Basisklassen in der Reihenfolge initialisiert, in der sie in einer Tiefe von links nach rechts des gerichteten azyklischen Graphen von Basisklassen erscheinen, wobei " von links nach rechts "ist die Reihenfolge des Auftretens der Basisklassen in der abgeleiteten Klassenbasisspezifiziererliste.
Dann werden direkte Basisklassen in der Deklarationsreihenfolge initialisiert, wie sie in der Basisspezifizierer-Liste erscheinen (unabhängig von der Reihenfolge der mem-Initialisierer).
Dann werden nicht statische Datenelemente in der Reihenfolge initialisiert, in der sie in der Klassendefinition deklariert wurden (wiederum unabhängig von der Reihenfolge der Mem-Initialisierer).
8 Schließlich wird das Compound-Statement des Konstruktors ausgeführt.
[Hinweis: Die Deklarationsreihenfolge ist erforderlich, um sicherzustellen, dass Base- und Member-Subobjekte in der umgekehrten Reihenfolge der Initialisierung zerstört werden. -Ende note]
Hervorhebung von mir
Wenn wir also bei Kugel aussehen 3 heißt es ausdrücklich, dass das Element in der Reihenfolge der in der Definition erscheinen konstruiert. Dies bedeutet, dass unabhängig von private
, public
oder wie sie in der Initialisierungsliste der Klassenmitglieder aufgeführt sind, sie in der Reihenfolge ihrer Deklaration erstellt werden.
Nicht statische Datenelemente werden in der Reihenfolge ihrer Deklaration initialisiert.
Durch den folgenden Code kompilieren können Sie dies testen, ob Sie Warnungen aktiviert:
// Example program
#include <iostream>
#include <string>
class Test {
private:
int a;
public:
int b;
Test() : a(0), b(0) {}
};
class TestPrivatePriority {
public:
int b;
TestPrivatePriority() : a(0), b(0) {}
private:
int a;
};
class TestPublicPriority {
private:
int a;
public:
int b;
TestPublicPriority() : b(0), a(0) {}
};
int main()
{
Test t;
TestPrivatePriority t1;
TestPublicPriority t2;
return 0;
}
Dies wird die folgende selbsterklärend Warnungen erzeugen:
In constructor 'TestPrivatePriority::TestPrivatePriority()':
25:9: warning: 'TestPrivatePriority::a' will be initialized after [-Wreorder]
20:9: warning: 'int TestPrivatePriority::b' [-Wreorder]
22:5: warning: when initialized here [-Wreorder]
In constructor 'TestPublicPriority::TestPublicPriority()':
35:9: warning: 'TestPublicPriority::b' will be initialized after [-Wreorder]
32:9: warning: 'int TestPublicPriority::a' [-Wreorder]
37:5: warning: when initialized here [-Wreorder]
- 1. C++ Zeiger auf Klassenelement des Objekts
- 2. Zugreifen auf C++ - Klassenelement in Inline-Assembly
- 3. Korrekte Initialisierungssequenz für Linux serielle Schnittstelle
- 4. ein Klassenelement entfernen
- 5. Zum nächsten Klassenelement scrollen
- 6. Bearbeiten Sie ein Klassenelement mit einer Methode in C#
- 7. Zeiger auf Klassenelement als Template-Parameter
- 8. Warum Klassenelement in ID verschachtelt Klassenelement in anderen CSS-Datei nicht überschrieben?
- 9. Machen Sie Klassenelement größer bei Hover
- 10. jQuery entfernen Klassenelement kommt immer wieder
- 11. Hinzufügen und Entfernen von Klassenelement-Kindern
- 12. MSVC2015 initialisiert Klassenelement, das nicht initialisiert werden soll
- 13. Pointer-Klassenelement bleibt NULL nach der Initialisierung durch Klassenmethode
- 14. Nicht alle Tags für bestimmte Klassenelement mit BeautifulSoup erhalten
- 15. Wenn ein Klassenelement von Array geändert wird, verhält es sich wie eine Kopie, keine Referenz
- 16. Template-Spezialisierung zur Verwendung des Standardtyps, wenn das Klassenelement typedef nicht existiert
- 17. Make Klassenelement Attribut des Typs Array (T) akzeptieren 2D-Arrays von T
- 18. Definierte Funktion, die const-Verweis auf Klassenelement und Kopie der Variablen zurückgibt
- 19. Wie wähle ich jedes andere Div Klassenelement mit nur CSS (keine js)
- 20. (Java) Wie kann man eine Nullzeiger-Ausnahme vermeiden, wenn man ein geschachteltes Klassenelement erhält?
- 21. Was ist der Einfluss von lazy = "false" auf das Klassenelement des NHibernate-Mappings?
- 22. C/C++/Objective-C-Texterkennungsbibliothek
- 23. Differenz zwischen scanf ("% c", & c) und scanf ("% c", & c)
- 24. Eye-Tracking-Bibliothek in C#, C/C++ oder Objective-C
- 25. Matlab in C C++ und C C++ in Matlab
- 26. C/C++/C#/VB-basierte Lexikalische Analysatoren
- 27. virtuelle Datei? in c/C++ oder C#
- 28. main() in C, C++, Java, C#
- 29. C/C++/C# SetWindowPos: Fenster über anderen
- 30. Einführung in C# für C/C++ - Benutzer
Bei Basisklasse ist es nicht ein Voreingenommenheit, es ist nur, dass Basiskonstruktor vor abgeleitet aufgerufen wird, der die Reihenfolge erzwingt. Zugriffsmodifizierer haben keinen Einfluss auf die Bestellung. Wie auch immer, Sie möchten vielleicht einen formellen Sprachanwaltsbeweis haben. Informell, um eine Intuition über die internen Abläufe zu bekommen, können Sie einige Beispielklassen schreiben, die ihre Namen aus Konstruktoren drucken und damit spielen, Mitglieder dieser Typen unter verschiedene Zugriffsmodifizierer zu setzen. – Drop