Statik sınıf üyelerinde çözümlenmemiş harici sembol


129

Çok basitçe söylemek gerekirse:

Çoğunlukla statik genel üyelerden oluşan bir sınıfım var, böylece diğer sınıflardan / işlevlerden çağrılması gereken benzer işlevleri bir arada gruplayabilirim.

Her neyse, sınıf genel kapsamımda iki statik işaretsiz char değişkeni tanımladım, bu değerleri aynı sınıfın yapıcısında değiştirmeye çalıştığımda, derlemede "çözülmemiş harici sembol" hatası alıyorum.

class test 
{
public:
    static unsigned char X;
    static unsigned char Y;

    ...

    test();
};

test::test() 
{
    X = 1;
    Y = 2;
}

C ++ 'da yeniyim, bu yüzden bana karşı dikkatli olun. Bunu neden yapamıyorum?

Yanıtlar:


145

X ve Y beyanlarınızla eşleşecek tanımları eklemeyi unuttunuz

unsigned char test::X;
unsigned char test::Y;

bir yerlerde. Statik bir üyeyi de başlatmak isteyebilirsiniz

unsigned char test::X = 4;

ve yine, bunu tanımda değil (genellikle bir CXX dosyasında) yaparsınız (genellikle bir .H dosyasında bulunur)


4
Yalnızca başlık içeren kitaplık yazıyorsanız, cpp dosyasından kaçınmak için bu tekniği kullanabilirsiniz: stackoverflow.com/questions/11709859/…
Shital Shah

62

Sınıf bildirimindeki statik veri üyeleri bildirimleri, bunların tanımı değildir. Bunları tanımlamak .CPPiçin, yinelenen sembollerden kaçınmak için bunu dosyada yapmalısınız .

Tanımlayabileceğiniz ve tanımlayabileceğiniz tek veri, integral statik sabitlerdir. (Değerlerienums sabit değerler olarak da kullanılabilir)

Kodunuzu şu şekilde yeniden yazmak isteyebilirsiniz:

class test {
public:
  const static unsigned char X = 1;
  const static unsigned char Y = 2;
  ...
  test();
};

test::test() {
}

Statik değişkenlerinizi değiştirme yeteneğiniz olmasını istiyorsanız (başka bir deyişle, onları const olarak bildirmek uygun olmadığında), kodunuzu .Hve arasında ayırabilirsiniz..CPP aşağıdaki şekilde arasında :

.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.
}

neden burada .CPP'de "işaretsiz karakter testi :: X = 1;" "test :: X = 1;" yerine? statik değişken X zaten tanımlanmış, neden hala "işaretsiz karakter" gerekiyor? @sergtk
Penny

@Penny Çünkü "test :: X = 1;" bir ödev olarak yorumlanır, oysa yapmaya çalıştığımız şey bir tanımdır.
Anonymous1847

4

Bu, genel olarak "statik sabit üyeli çözülmemiş harici öğeler" ararken benim için ortaya çıkan ilk SO iş parçacığı olduğundan, burada çözülmemiş dışsallarla bir sorunu çözmek için başka bir ipucu bırakacağım:

Benim için unuttuğum şey sınıf tanımımı işaretlemekti __declspec(dllexport)ve başka bir sınıftan çağrıldığında (o sınıfın dll sınırlarının dışında), elbette çözülmemiş dış hatamı aldım.
Yine de, dahili bir yardımcı sınıfı başka bir yerden erişilebilen bir sınıfla değiştirirken unutulması kolaydır, bu nedenle dinamik olarak bağlantılı bir projede çalışıyorsanız, bunu da kontrol edebilirsiniz.


2

benim durumumda .h dosyasında bir statik değişken tanımladım.

//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}

ve myClass.cpp'de bu m_nMyVar'ı kullanmayı denedim. Şunun gibi LINK hatası aldı:

hata LNK2001: çözümlenmemiş harici sembol "public: statik sınıf ... Bağlantı hatasıyla ilgili cpp dosyası şöyle görünür:

//myClass.cpp
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}

Bu yüzden myClass.cpp'nin üstüne aşağıdaki kodu ekliyorum

//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
}

sonra LNK2001 gitti.


0

Benim durumumda yanlış bağlantı kullanıyordum.
C ++ (cli) yönetildi, ancak yerel dışa aktarma ile. Bağlayıcı -> girdi -> derleme bağlantı kaynağına fonksiyonun dışa aktarıldığı kitaplığın dll'sini ekledim. Ancak yerel c ++ bağlantısı, .lib dosyasının cpp'deki uygulamaları doğru bir şekilde "görmesini" gerektirir, bu nedenle .lib dosyasını linker -> input -> ek bağımlılıklara eklememe yardımcı oldu.
[Genellikle yönetilen kod dll verme ve alma işlemlerini kullanmaz, referans kullanır, ancak bu benzersiz bir durumdur.]

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.