2013-02-22 8 views
7

my_test.hSollte eine konstante statische Variable in einer C++ Header-Datei initialisiert werden?

#ifndef MY_TEST 
#define MY_TEST 

struct obj { 
    int x; 
    int y; 
}; 

class A { 
private: 
    const static int a=100; 
    const static obj b; 
}; 

const obj A::b={1,2}; 

#endif 

Wenn cav der Erstellung dieser Header-Datei verwendet wird, ein Fehler 'multiple definition of 'A::b' auftritt.

  1. warum ist das, wenn ich Guard Makro bereits verwendet habe?
  2. warum produziert A::a nicht die erro? (Ich kann nicht Code const static obj b={1,2} in class A schreiben)

Antwort

4

warum ist das, wenn ich Guard Makro bereits verwendet habe?

Kopfschutz nur die Aufnahme der Inhalte Header-Datei verhindert mehr als einmal in den gleichen translation unit nicht über mehrere Übersetzungseinheiten.

warum ist A::a nicht die Fehlermeldung (ich kann keinen Code schreiben const static obj b={1,2} in class A)

In-class initialization vom Compiler als Sonderfall für statische Datenelemente erlaubt ist von const literalem Typ. Ihr Beispiel ist In-Class-Initialisierung.

const A::b definiert den gleichen Symbolnamen in jeder Übersetzungseinheit, in der die Kopfzeile enthalten ist, und bricht damit die one definition rule.

Sie müssen die Definition in eine einzige cpp-Quelldatei verschieben, sodass sie nur einmal definiert wird.

+2

Für das OP, als Anfänger, ist das "Sie müssen" korrekt. Als absolute technische Aussage ist dies jedoch nicht der Fall, da es für Klassenvorlagen eine ODR-Ausnahme gibt. Das heißt technisch, wenn es wirklich notwendig ist, kann man die statische Konstante in einer Klassenvorlage definieren und dann von einer beliebigen Spezialisierung erben. Es wird manchmal als Templatestrick bezeichnet. Eine praktikablere Möglichkeit, eine Implementierungsdatei zu vermeiden, besteht darin, über eine Inline-Funktion (die die Konstante als lokal haben kann) Zugriff auf die Konstante bereitzustellen. –

+0

@Alf: Ich stimme zu, was Ihr Kommentar sagt. In der Tat ist das eine gute Information. –

0

Das Problem ist Ihre Definition von A::b keinen Typ enthält. Um eine gültige Definition zu sein, sollte es sein:

const obj A::b = {1, 2}; 

Diese Beseitigung der Kompilierungsfehler erhalten wird, aber Sie werden immer noch Linker Fehler erhalten, wenn Sie diesen Header in mehr als einer Quelldatei enthalten, weil A::b wird Multiplikation definiert dann. Sie sollten die Definition in eine CPP-Datei verschieben.

0

Unabhängig davon, ob Sie einen Header Guard haben oder nicht, bedeutet dies, dass Sie eine Instanz von A::b in jeder Quelldatei erhalten, die diese Header-Datei enthält. Daher der Linkerfehler.

Also, im Allgemeinen ist es möglich, aber keine gute Idee.

1

Alok hat bereits beantwortet Ihre Frage, aber hier sind ein paar einfachen Faustregeln, in leicht zu merken Form:

  1. Erklärungen
  2. Definitionen in der H-Datei gehen geh in die.CPP-Datei

Daher müssen statische Mitglieder erklärt in der H-Datei sein, und dann in der CPP-Datei definiert. In Ihrem Fall korrigieren Sie die Syntax für die Deklarationen und verschieben Sie sie dann in die Datei "my_test.cpp".

Verwandte Themen