Nicht aufgelöstes externes Symbol auf statischen Klassenmitgliedern
Lesezeit: 4 Minuten
Ganz einfach gesagt:
Ich habe eine Klasse, die hauptsächlich aus statischen öffentlichen Mitgliedern besteht, sodass ich ähnliche Funktionen zusammenfassen kann, die noch von anderen Klassen/Funktionen aufgerufen werden müssen.
Wie auch immer, ich habe zwei statische unsigned char-Variablen in meinem öffentlichen Gültigkeitsbereich der Klasse definiert. Wenn ich versuche, diese Werte im Konstruktor derselben Klasse zu ändern, erhalte ich bei der Kompilierung einen Fehler “nicht aufgelöstes externes Symbol”.
class test
{
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
test::test()
{
X = 1;
Y = 2;
}
Ich bin neu in C++, also schonen Sie mich. Warum kann ich das nicht?
Colin Jensen
Wenn Sie verwenden C++ 17 du kannst einfach die verwenden inline Bezeichner (siehe https://stackoverflow.com/a/11711082/55721)
Wenn Sie ältere Versionen des C++-Standards verwenden, müssen Sie die Definitionen hinzufügen, die Ihren Deklarationen von X und Y entsprechen
unsigned char test::X;
unsigned char test::Y;
irgendwo. Möglicherweise möchten Sie auch ein statisches Mitglied initialisieren
unsigned char test::X = 4;
und wieder tun Sie dies in der Definition (normalerweise in einer CXX-Datei) und nicht in der Deklaration (die sich häufig in einer .H-Datei befindet).
Wenn Sie eine Nur-Header-Bibliothek schreiben, können Sie diese Technik verwenden, um eine cpp-Datei zu vermeiden: stackoverflow.com/questions/11709859/…
– Shital Shah
18. November 2016 um 18:49 Uhr
Deklarationen statischer Datenelemente in der Klassendeklaration sind keine Definition von ihnen. Um sie zu definieren, sollten Sie dies in der tun .CPP Datei, um doppelte Symbole zu vermeiden.
Die einzigen Daten, die Sie deklarieren und definieren können, sind ganzzahlige statische Konstanten. (Werte von enums können auch als konstante Werte verwendet werden)
Vielleicht möchten Sie Ihren Code wie folgt umschreiben:
class test {
public:
const static unsigned char X = 1;
const static unsigned char Y = 2;
...
test();
};
test::test() {
}
Wenn Sie die Möglichkeit haben möchten, Ihre statischen Variablen zu ändern (mit anderen Worten, wenn es unangemessen ist, sie als konstant zu deklarieren), können Sie Ihren Code zwischen ihnen trennen .H und .CPP auf die folgende Weise:
.H :
class test {
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
.CPP:
unsigned char test::X = 1;
unsigned char test::Y = 2;
test::test()
{
// constructor is empty.
// We don't initialize static data member here,
// because static data initialization will happen on every constructor call.
}
warum hier in .CPP, es ist “unsigned char test::X = 1;” statt “test::X = 1;”? statische Variable X bereits definiert, warum noch “unsigned char”? @sergtk
– Penny
18. September 2018 um 22:56 Uhr
@Penny Weil “test::X = 1;” wird als Auftrag interpretiert, während wir versuchen, eine Definition zu machen.
– Anonym1847
29. April 2020 um 6:42 Uhr
In meinem Fall habe ich eine statische Variable in der .h-Datei deklariert, z
//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}
und in myClass.cpp habe ich versucht, diese m_nMyVar zu verwenden. Es hat LINK-Fehler wie:
Fehler LNK2001: nicht aufgelöstes externes Symbol “öffentlich: statische Klasse … Die cpp-Datei für den Linkfehler sieht folgendermaßen aus:
//myClass.cpp
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
Also füge ich den folgenden Code oben in myClass.cpp hinzu
//myClass.cpp
int myClass::m_nMyVar; //it seems redefine m_nMyVar, but it works well
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
dann ist LNK2001 weg.
Johann Studanski
Da dies der erste SO-Thread ist, der bei der Suche nach “nicht aufgelösten Externals mit statischen Konstantenmitgliedern” im Allgemeinen für mich aufzutauchen schien, werde ich hier einen weiteren Hinweis hinterlassen, um ein Problem mit nicht aufgelösten Externals zu lösen:
Für mich war das, was ich vergessen habe, meine Klassendefinition zu markieren __declspec(dllexport)und wenn ich von einer anderen Klasse (außerhalb der DLL-Grenzen dieser Klasse) aufgerufen wurde, bekam ich natürlich meinen ungelösten externen Fehler.
Trotzdem wird es leicht vergessen, wenn Sie eine interne Hilfsklasse in eine ändern, auf die von anderswo aus zugegriffen werden kann. Wenn Sie also in einem dynamisch verknüpften Projekt arbeiten, können Sie dies auch überprüfen.
Wenn wir eine statische Variable in einer Klasse deklarieren, wird sie von allen Objekten dieser Klasse geteilt. Da statische Variablen nur einmal initialisiert werden, werden sie niemals von einem Konstruktor initialisiert. Stattdessen sollte die statische Variable nur einmal explizit außerhalb der Klasse mit dem Bereichsauflösungsoperator (::) initialisiert werden.
Im folgenden Beispiel ist die statische Variable counter ein Mitglied der Klasse Demo. Beachten Sie, wie es explizit außerhalb der Klasse mit dem Anfangswert = 0 initialisiert wird.
#include <iostream>
#include <string>
using namespace std;
class Demo{
int var;
static int counter;
public:
Demo(int var):var(var){
cout<<"Counter = "<<counter<<endl;
counter++;
}
};
int Demo::counter = 0; //static variable initialisation
int main()
{
Demo d(2), d1(10),d3(1);
}
Output:
Count = 0
Count = 1
Count = 2
was_falsch_hier
In meinem Fall habe ich eine falsche Verknüpfung verwendet.
Es wurde c++ (cli) verwaltet, aber mit nativem Export. Ich habe Linker -> Input -> Assembly Link Resource die DLL der Bibliothek hinzugefügt, aus der die Funktion exportiert wird. Das native C++-Linking erfordert jedoch eine .lib-Datei, um Implementierungen in cpp korrekt zu “sehen”, daher hat es mir geholfen, die .lib-Datei zu Linker -> Eingabe -> zusätzliche Abhängigkeiten hinzuzufügen.
[Usually managed code does not use dll export and import, it uses references, but that was unique situation.]
9948500cookie-checkNicht aufgelöstes externes Symbol auf statischen Klassenmitgliedernyes