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?

Nicht aufgelostes externes Symbol auf statischen Klassenmitgliedern
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.

Nicht aufgelostes externes Symbol auf statischen Klassenmitgliedern
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

1647109811 543 Nicht aufgelostes externes Symbol auf statischen Klassenmitgliedern
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.]

994850cookie-checkNicht aufgelöstes externes Symbol auf statischen Klassenmitgliedern

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy