2009-04-06 11 views
15

Wo ist der richtige Ort zum Initialisieren eines Klassendatenelements? Ich habe die Erklärung Klasse in einer Header-Datei wie folgt aus:Korrekter Ort zum Initialisieren von Klassenvariablen?

foo.h:

class Foo { 
private: 
    int myInt; 
}; 

Dann habe ich versuchen, einen Wert myInt in der entsprechenden CPP-Datei zu setzen:

Foo. cpp:

int Foo::myInt = 1; 

Ich bekomme einen Compiler-Fehler für die Neudefinition von MyInt. Was mache ich falsch???

Antwort

28

Was Sie dort haben, ist eine Instanzvariable. Jede Instanz der Klasse erhält ihre eigene Kopie von myInt. Der Ort, diejenigen zu initialisieren ist in einem Konstruktor:

class Foo { 
private: 
    int myInt; 
public: 
    Foo() : myInt(1) {} 
}; 

Eine Klassenvariable ist ein, wo es nur eine Kopie ist, die von jeder Instanz der Klasse geteilt wird. Diese können initialisiert werden, wie Sie es versucht haben. (Siehe JaredPar Antwort für die Syntax)

Für ganzzahlige Werte haben Sie auch die Möglichkeit, einen statischen const rechts in der Klassendefinition Initialisierung:

class Foo { 
private: 
    static const int myInt = 1; 
}; 

Dies ist ein einzelner Wert von allen Instanzen der gemeinsame Klasse, die nicht geändert werden kann.

+2

Hallo, können Sie mir sagen, wie heißt die 'Foo(): myInt (1) {}' - Syntax, damit ich sie googlen und ausführlicher einlesen kann? Ist es das gleiche wie 'public: Foo() {myInt = 1; } '? – SexyBeast

+5

@Cupidvogel: Sie sind "Member initialiser lists" (http://en.cppreference.com/w/cpp/language/initializer_list) – Eclipse

1

Eine Klassenvariable muss als "statisch" gekennzeichnet sein. Wenn Ihre Variable eine Instanzvariable und keine Klassenvariable ist, müssen Sie sie im Konstruktor oder in einer anderen Methode initialisieren.

4

Sie versuchen, ein Instanzmitglied über ein statisches Initialisierungskonstrukt zu initialisieren. Wenn Sie möchten, dass dies eine Variable auf Klassenebene (statisch) ist, dann müssen Sie der Variablen das Schlüsselwort static voranstellen.

class Foo { 
private: 
    static int myInt; 
}; 
+0

Vielen Dank! Ich nehme an, dass eine "Variable auf Klassenebene" eine ist, die nur innerhalb einer Klasse und nirgendwo sonst verwendet werden kann? –

+0

@draftomatic, durch die Variable auf Klassenebene meine ich eine, die keiner Instanz der Klasse zugeordnet ist. Innerhalb nur Foo (und es ist Freunde) können Sie einfach sagen Foo :: myInt. Es ist keine Instanz von Foo erforderlich. – JaredPar

10

Um auf Jareds Antwort zu erweitern, müssen Sie es in den Konstruktor einfügen, wenn Sie es so initialisieren möchten, wie es jetzt ist.

class Foo 
{ 
public: 
    Foo(void) : 
    myInt(1) // directly construct myInt with 1. 
    { 
    } 

    // works but not preferred: 
    /* 
    Foo(void) 
    { 
     myInt = 1; // not preferred because myInt is default constructed then assigned 
        // but with POD types this makes little difference. for consistency 
        // however, it's best to put it in the initializer list, as above 
        // Edit, from comment: Also, for const variables and references, 
        // they must be directly constructed with a valid value, so they 
        // must be put in the initializer list. 
    } 
    */ 

private: 
    int myInt; 
}; 
+0

Gut für die Erklärung von +1 Methode, beschreibt Vorteile/Nachteile und für die Beschreibung der Terminologie der "Initialisiererliste" (die für Programmierer, die aus anderen Sprachen kommen, sehr unterschiedlich von der Beschreibung "in einem Konstruktor" der angenommenen Antwort aussieht; "in einem Konstruktor" befindet sich zwischen den geschweiften Klammern des Konstruktors.Und diese Antwort fasst alles für mich zusammen. –

Verwandte Themen