Mówiąc najprościej:
Mam klasę, która składa się głównie ze statycznych publicznych elementów członkowskich, więc mogę grupować razem podobne funkcje, które nadal muszą być wywoływane z innych klas / funkcji.
W każdym razie zdefiniowałem dwie statyczne zmienne typu unsigned char w zakresie publicznym mojej klasy, kiedy próbuję zmodyfikować te wartości w konstruktorze tej samej klasy, podczas kompilacji pojawia się błąd „nierozwiązany symbol zewnętrzny”.
class test
{
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
test::test()
{
X = 1;
Y = 2;
}
Jestem nowy w C ++, więc nie przejmuj się. Dlaczego nie mogę tego zrobić?
Deklaracje składowych danych statycznych w deklaracji klasy nie są ich definicją. Aby je zdefiniować, należy to zrobić w
.CPP
pliku, aby uniknąć powielania symboli.Jedyne dane, które można zadeklarować i zdefiniować, to integralne stałe statyczne. (Wartości od
enums
mogą być również używane jako wartości stałe)Możesz przepisać swój kod jako:
class test { public: const static unsigned char X = 1; const static unsigned char Y = 2; ... test(); }; test::test() { }
Jeśli chcesz mieć możliwość modyfikowania zmiennych statycznych (innymi słowy, gdy deklarowanie ich jako stałych jest niewłaściwe), możesz oddzielić swój kod między
.H
i.CPP
w następujący sposób:.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. }
źródło
Ponieważ jest to pierwszy wątek SO, który pojawił się podczas wyszukiwania „nierozwiązanych zewnętrznych elementów ze statycznymi elementami stałymi”, zostawię tutaj kolejną wskazówkę dotyczącą rozwiązania jednego problemu z nierozwiązanymi zewnętrznymi elementami:
Dla mnie zapomniałem o zaznaczeniu definicji mojej klasy
__declspec(dllexport)
, a gdy zostałem wywołany z innej klasy (poza granicami biblioteki DLL tej klasy), oczywiście otrzymałem nierozwiązany błąd zewnętrzny.Mimo to, łatwo jest zapomnieć, kiedy zmieniasz wewnętrzną klasę pomocniczą na taką, która jest dostępna z innego miejsca, więc jeśli pracujesz w dynamicznie połączonym projekcie, równie dobrze możesz to sprawdzić.
źródło
w moim przypadku zadeklarowałem jedną zmienną statyczną w pliku .h, na przykład
//myClass.h class myClass { static int m_nMyVar; static void myFunc(); }
aw myClass.cpp próbowałem użyć tego m_nMyVar. Wystąpił błąd LINK, taki jak:
błąd LNK2001: nierozwiązany symbol zewnętrzny „public: klasa statyczna ... Plik cpp powiązany z błędem łącza wygląda następująco:
//myClass.cpp void myClass::myFunc() { myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error }
Więc dodaję poniższy kod na górze myClass.cpp
//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 }
wtedy LNK2001 zniknie.
źródło
W moim przypadku użyłem złego linkowania.
Był zarządzany C ++ (CLI), ale z natywnym eksportowaniem. Dodałem do linkera -> dane wejściowe -> zasób łącza zestawu dll biblioteki, z której eksportowana jest funkcja. Ale natywne linkowanie c ++ wymaga pliku .lib, aby poprawnie "zobaczyć" implementacje w cpp, więc pomogło mi dodać plik .lib do konsolidatora -> wejście -> dodatkowe zależności.
[Zwykle zarządzany kod nie wykorzystuje eksportu i importu dll, używa odwołań, ale to była wyjątkowa sytuacja.]
źródło