2009-07-07 5 views
1

Ich habe eine globale Variable:Warum gibt das Entfernen von const Linkfehler?

const std::string whiteSpaceBeforeLeadingCmntOption = "WhiteSpaceBeforeLeadingComment"; 

Wenn ich die const auf dieser Variablendeklaration zu entfernen, erhalte ich viele Vorkommen des folgenden Linkfehler:

error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > whiteSpaceBeforeLeadingCmntOption" ([email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@A) already defined in REGISTER_TO_UNSRLZ.obj 

Dies ist in einer .h-Datei, das ist an verschiedenen Stellen enthalten, aber ich habe eine #ifndef-Band darauf, um es an mehreren Stellen zu vermeiden. Irgendwelche Ideen, woraus der Fehler besteht?

Antwort

5

Dies funktioniert, wenn Sie const in der .h haben, da const impliziert statisch, so dass Sie die gleiche Variable in mehreren Compilands haben können.

Durch Entfernen von const für eine Variable, die in einer .h-Datei definiert ist, erstellen Sie mehrere Instanzen mit demselben Bezeichner innerhalb desselben Programms.

Wenn Sie const entfernen müssen, in der .h, könnten Sie tun:

extern std::string whiteSpaceBeforeLeadingCmntOption; 

Und dann haben:

std::string whiteSpaceBeforeLeadingCmntOption = ""; 

In einem Ihrer CPP-Dateien.

+0

+1 für mich, um es –

5

Das Problem ist, dass durch Definition in der Header-Datei in jeder Kompilierungseinheit, die diese Header-Datei enthält, instanziiert wird, was dazu führt, dass es für die Link-Stufe mehrfach definiert wird.

Was möchten Sie tun ist dies in Ihrer .h erklären:

extern std::string whiteSpaceBeforeLeadingCmntOption; 

und dann in einem einzigen cpp erklären:

std::string whiteSpaceBeforeLeadingCmntOption = "WhiteSpaceBeforeLeadingComment"; 
1

Denn wenn Ihr Kopf in mehreren enthalten ist cpp-Dateien, dann haben Sie mehrere Definitionen derselben Variablen (hier eine globale). Es ist verboten von der Sprache.

Was Sie wollen, ist die Deklaration und die Definition zu trennen:

Header:

extern std::string whiteSpaceBeforeLeadingCmntOption; // declaration 
// the 'extern' keyword is here to be sure the linker will look in all cpp for the definition of this variable 

in einem cav:

std::string whiteSpaceBeforeLeadingCmntOption = "WhiteSpaceBeforeLeadingComment"; // definition 

Das für die Klasse statische Variablen zu wahr ist.

Aber wenn das Objekt const ist, dann wird der Compiler nur eine Definition des const-Objekts machen und sie irgendwo in den Lesespeicher legen. Sie müssen nicht angeben, in welcher Kompilierungseinheit sie definiert ist.

2

Das #ifndef-Sentinel verhindert nur, dass jede Datei es mehr als einmal einfügt.

+0

in der Antwortdatei zu schlagen sollte als ‚Übersetzungseinheit‘ gelesen werden. +1, wie es ein häufiger Fehler ist. –

3

in C++ die Namen von const Objekte sind Lokal der Übersetzungseinheit sie auftreten oder #include in.

Verwandte Themen