Saya memiliki dua kelas yang dideklarasikan sebagai berikut:
class User
{
public:
MyMessageBox dataMsgBox;
};
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message> *dataMessageList;
};
Ketika saya mencoba mengkompilasinya menggunakan gcc, itu memberikan kesalahan berikut:
MyMessageBox tidak menyebutkan sebuah tipe
g++
dan bukangcc
Jawaban:
Ketika kompilator mengkompilasi kelas
User
dan sampai keMyMessageBox
baris,MyMessageBox
belum ditentukan. Kompilator tidak memiliki ideMyMessageBox
, jadi tidak dapat memahami arti dari anggota kelas Anda.Anda perlu memastikan
MyMessageBox
sudah ditentukan sebelum Anda menggunakannya sebagai anggota. Ini diselesaikan dengan membalik urutan definisi. Namun, Anda memiliki ketergantungan siklik: jika Anda pindah keMyMessageBox
atasUser
, maka definisiMyMessageBox
namanyaUser
tidak akan ditentukan!Apa yang dapat Anda lakukan adalah menyatakan ke depan
User
; yaitu, nyatakan tetapi jangan definisikan. Selama kompilasi, tipe yang dideklarasikan tetapi tidak ditentukan disebut tipe tidak lengkap . Pertimbangkan contoh yang lebih sederhana:Dengan mendeklarasikan terus
User
,MyMessageBox
masih bisa membentuk sebuah pointer atau referensi ke sana:Anda tidak dapat melakukan ini sebaliknya: seperti yang disebutkan, seorang anggota kelas perlu memiliki definisi. (Alasannya adalah bahwa kompilator perlu mengetahui berapa banyak memori yang digunakan
User
, dan mengetahui bahwa ia perlu mengetahui ukuran anggotanya.) Jika Anda mengatakan:Itu tidak akan berhasil, karena belum tahu ukurannya.
Di samping catatan, fungsi ini:
Mungkin tidak boleh mengambil salah satu dari mereka dengan penunjuk. Anda tidak dapat mengirim pesan tanpa pesan, Anda juga tidak dapat mengirim pesan tanpa pengguna untuk mengirimkannya. Dan kedua situasi tersebut dapat diekspresikan dengan meneruskan null sebagai argumen ke salah satu parameter (null adalah nilai penunjuk yang benar-benar valid!)
Sebaliknya, gunakan referensi (mungkin const):
sumber
MyMessageBox
sudah cukup. Bagaimana jikaMyMessageBox
memiliki variabel tipeUser
juga - apakah itu akan menjadi jalan buntu?User
akan memilikiMessageBox
mana yang akan memilikiUser
, yang akan memilikiMessageBox
yang akan memilikiUser
, yang akan memilikiMessageBox
yang akan memilikiUser
, yang akan memilikiMessageBox
yang akan memilikiUser
...sumber
Kompiler C ++ memproses masukan mereka satu kali. Setiap kelas yang Anda gunakan harus sudah ditentukan terlebih dahulu. Anda gunakan
MyMessageBox
sebelum Anda mendefinisikannya. Dalam kasus ini, Anda cukup menukar dua definisi kelas.sumber
MyMessageBox
memilikiUser
tipe dalam deklarasi metodenya.User
. Perbedaan penting, karena itu berarti kelas Pengguna hanya perlu dideklarasikan pada saat itu, bukan ditentukan . Tapi lihat posting ekstensif GMan.User
tipe belum dideklarasikan.Anda perlu mendefinisikan MyMessageBox sebelum User - karena User menyertakan objek MyMessageBox berdasarkan nilai (dan karenanya compiler harus mengetahui ukurannya).
Anda juga harus meneruskan deklarasi Pengguna sebelum MyMessageBox - karena MyMessageBox menyertakan anggota tipe Pengguna *.
sumber
Pada catatan terkait, jika Anda memiliki:
Kemudian itu juga akan berfungsi, karena Pengguna didefinisikan di MyMessageBox sebagai penunjuk
sumber
Anda harus mendeklarasikan prototipe itu sebelum menggunakannya:
edit : Menukar tipe
sumber
Itu selalu didorong dalam C ++ bahwa Anda memiliki satu kelas per file header, lihat diskusi ini di SO [ 1 ]. Jawaban GManNickG menjelaskan mengapa ini terjadi. Tetapi cara terbaik untuk mengatasi ini adalah dengan meletakkan
User
kelas di satu file header (User.h
) danMyMessageBox
kelas di file header lain (MyMessageBox.h
). Kemudian dalam diri AndaUser.h
Anda termasukMyMessageBox.h
dan di dalamMyMessageBox.h
Anda termasukUser.h
. Jangan lupa "include gaurds" [ 2 ] agar kode Anda berhasil dikompilasi.sumber