Коли компілятор компілює клас User
і потрапляє до MyMessageBox
рядка, MyMessageBox
він ще не визначений. Компілятор поняття не маєMyMessageBox
, тому не може зрозуміти значення вашого класу.
Ви повинні переконатися, що MyMessageBox
визначено, перш ніж використовувати його як член. Це вирішується шляхом обернення порядку визначення. Однак у вас є циклічна залежність: якщо ви рухаєтеся MyMessageBox
вище User
, то у визначенні MyMessageBox
імені User
не буде визначено!
Що ви можете зробити, це передати заявити User
; тобто оголосити це, але не визначати. Під час компіляції тип, який оголошується, але не визначається, називається неповним типом . Розглянемо простіший приклад:
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;
}
За вперед оголошуючи User
, MyMessageBox
все ще може сформувати покажчик або посилання на нього:
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;
};
Ви не можете зробити це навпаки: як було зазначено, для класу необхідно мати визначення. (Причина полягає в тому, що компілятору необхідно знати, скільки пам'яті User
займає, і знати, що він повинен знати розмір своїх членів.) Якби сказати:
class MyMessageBox;
class User
{
public:
// size not available! it's an incomplete type
MyMessageBox dataMsgBox;
};
Це не буде працювати, оскільки він ще не знає розміру.
Зі сторони, ця функція:
void sendMessage(Message *msg, User *recvr);
Ймовірно, не слід брати жодного з цих вказівників. Ви не можете надсилати повідомлення без повідомлення, а також не можете надсилати повідомлення без користувача, до якого його можна надіслати. І обидві ці ситуації виразні, передаючи null як аргумент будь-якому параметру (null - цілком дійсне значення вказівника!)
Швидше скористайтеся посиланням (можливо, const):
void sendMessage(const Message& msg, User& recvr);