Simbol eksternal yang tidak terselesaikan pada anggota kelas statis

129

Sederhananya:

Saya memiliki kelas yang sebagian besar terdiri dari anggota publik statis, jadi saya dapat mengelompokkan fungsi-fungsi serupa bersama-sama yang masih harus dipanggil dari kelas / fungsi lain.

Lagi pula, saya telah mendefinisikan dua variabel char unsigned statis dalam lingkup publik kelas saya, ketika saya mencoba untuk memodifikasi nilai-nilai ini di konstruktor kelas yang sama, saya mendapatkan kesalahan "simbol eksternal yang belum terselesaikan" pada kompilasi.

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

    ...

    test();
};

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

Saya baru mengenal C ++ jadi mudah saja. Mengapa saya tidak bisa melakukan ini?

AustinWBryan
sumber

Jawaban:

145

Anda lupa menambahkan definisi yang cocok dengan deklarasi X dan Y Anda

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

suatu tempat. Anda mungkin ingin juga menginisialisasi anggota statis

unsigned char test::X = 4;

dan sekali lagi, Anda melakukannya dalam definisi (biasanya dalam file CXX) tidak dalam deklarasi (yang sering dalam file .H)

Colin Jensen
sumber
4
Jika Anda menulis pustaka khusus header, Anda dapat menggunakan teknik ini untuk menghindari file cpp: stackoverflow.com/questions/11709859/...
Shital Shah
62

Deklarasi anggota data statis dalam deklarasi kelas bukan definisi mereka. Untuk mendefinisikannya, Anda harus melakukan ini di .CPPfile untuk menghindari simbol yang digandakan.

Satu-satunya data yang dapat Anda deklarasikan dan tentukan adalah konstanta statis integral. (Nilai enumsdapat digunakan sebagai nilai konstan juga)

Anda mungkin ingin menulis ulang kode Anda sebagai:

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

test::test() {
}

Jika Anda ingin memiliki kemampuan untuk mengubah Anda variabel statis (dengan kata lain ketika tidak pantas untuk mendeklarasikan mereka sebagai const), Anda dapat memisahkan kode Anda antara .Hdan .CPPdengan cara berikut:

.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.
}
sergtk
sumber
mengapa di sini di .CPP, itu adalah "tes char unsigned :: X = 1;" bukannya "test :: X = 1;"? variabel statis X sudah didefinisikan, mengapa masih perlu "unsigned char"? @sergtk
Penny
@Penny Karena "test :: X = 1;" ditafsirkan sebagai tugas, sedangkan yang kami coba lakukan adalah definisi.
Anonymous1847
4

Karena ini adalah utas SO pertama yang sepertinya muncul untuk saya ketika mencari "eksternal yang tidak terselesaikan dengan anggota const statis" secara umum, saya akan meninggalkan petunjuk lain untuk menyelesaikan satu masalah dengan eksternal yang belum terselesaikan di sini:

Bagi saya, hal yang saya lupa adalah menandai definisi kelas saya __declspec(dllexport), dan ketika dipanggil dari kelas lain (di luar batas kelas dll), saya tentu saja mendapatkan kesalahan eksternal yang belum terselesaikan.
Namun, mudah untuk dilupakan ketika Anda mengubah kelas pembantu internal menjadi kelas yang dapat diakses dari tempat lain, jadi jika Anda bekerja dalam proyek yang terhubung secara dinamis, Anda mungkin perlu memeriksanya juga.

Johann Studanski
sumber
2

dalam kasus saya, saya mendeklarasikan satu variabel statis dalam file .h, seperti

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

dan di myClass.cpp, saya mencoba menggunakan m_nMyVar ini. Itu mendapat kesalahan LINK seperti:

kesalahan LNK2001: simbol eksternal yang tidak terselesaikan "publik: kelas statis ... File cpp terkait kesalahan tautan terlihat seperti:

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

Jadi saya menambahkan kode di bawah ini di bagian atas 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
}

maka LNK2001 hilang.

Sen dolar
sumber
0

Dalam kasus saya, saya menggunakan tautan yang salah.
Itu dikelola c ++ (cli) tetapi dengan ekspor asli. Saya telah menambahkan ke linker -> input -> assembly link resource dll dari perpustakaan tempat fungsi diekspor. Tetapi penautan c ++ asli membutuhkan file .lib untuk "melihat" implementasi dalam cpp dengan benar, jadi bagi saya membantu menambahkan file .lib ke linker -> input -> dependensi tambahan.
[Biasanya kode yang dikelola tidak menggunakan ekspor dan impor dll, itu menggunakan referensi, tapi itu situasi yang unik.]

whats_wrong_here
sumber