Derleyici sınıfı derlediğinde User
ve MyMessageBox
satıra geldiğinde , MyMessageBox
henüz tanımlanmamıştır. Derleyicinin hiçbir fikri MyMessageBox
yoktur, bu nedenle sınıf üyenizin anlamını anlayamaz.
Daha önceMyMessageBox
tanımlandığından emin olmalısınÜye olarak kullanmadan . Bu, tanım sırasını tersine çevirerek çözülür. Ancak, bir döngüsel bağımlılığı: Eğer taşırsanız MyMessageBox
yukarıdaki User
sonra tanımındaki MyMessageBox
adı User
tanımlanamaz olacak!
Yapabilecekleriniz ileriye doğru beyan etmektir User
; yani ilan edin ama tanımlamayın. Derleme sırasında, bildirilen ancak tanımlanmayan bir türe tamamlanmamış tür denir . Daha basit örneği düşünün:
struct foo; // foo is *declared* to be a struct, but that struct is not yet defined
struct bar
{
// this is okay, it's just a pointer;
// we can point to something without knowing how that something is defined
foo* fp;
// likewise, we can form a reference to it
void some_func(foo& fr);
// but this would be an error, as before, because it requires a definition
/* foo fooMember; */
};
struct foo // okay, now define foo!
{
int fooInt;
double fooDouble;
};
void bar::some_func(foo& fr)
{
// now that foo is defined, we can read that reference:
fr.fooInt = 111605;
fr.foDouble = 123.456;
}
İleri beyan ederek User
, MyMessageBox
yine de bir işaretçi veya ona referans oluşturabilir:
class User; // let the compiler know such a class will be defined
class MyMessageBox
{
public:
// this is ok, no definitions needed yet for User (or Message)
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message>* dataMessageList;
};
class User
{
public:
// also ok, since it's now defined
MyMessageBox dataMsgBox;
};
Sen yapamazsın etrafında bu başka bir yol yapın: belirtildiği gibi, bir sınıf üyesi bir tanım olması gerekir. (Bunun nedeni, derleyicinin ne kadar bellek kapladığını User
bilmesi ve üyelerinin boyutunu bilmesi gerektiğini bilmesi gerektiğidir.)
class MyMessageBox;
class User
{
public:
// size not available! it's an incomplete type
MyMessageBox dataMsgBox;
};
Henüz boyutunu bilmediği için işe yaramaz.
Bir yan not olarak, bu işlev:
void sendMessage(Message *msg, User *recvr);
Muhtemelen bunların ikisini de işaretçi ile almamalı. Mesaj olmadan mesaj gönderemezsiniz veya kullanıcı göndermeden mesaj gönderemezsiniz. Ve bu iki durum da, her iki parametreye de argüman olarak null iletilerek ifade edilebilir (null, tamamen geçerli bir işaretçi değeridir!)
Bunun yerine, bir referans kullanın (muhtemelen sabit):
void sendMessage(const Message& msg, User& recvr);