2016-11-16 1 views
2

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

+0

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

Antwort

3

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.

1

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] 
Verwandte Themen