У меня есть два класса, объявил как указано ниже:
class User
{
public:
MyMessageBox dataMsgBox;
};
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message> *dataMessageList;
};
Когда я пытаюсь скомпилировать его с помощью gcc, это дает следующую ошибку:
MyMessageBox не называет тип
Когда компилятор компиляторует пользователь класса
и попадает в строку MyMessagebox
, MyMessageBox
еще не определен. Компилятор не имеет представления MyMessageBox
, поэтому не может понять значение вашего класса.
Вам необходимо убедиться MyMessageBox
до Вы используете его в качестве члена. Это решается обратным по порядку определения. Тем не менее, у вас есть циклическая зависимость: если вы переместите MyMessagebox
выше USER
, то в определении MyMessageBox
Имя У пользователя
T быть определен!
То, что вы можете сделать, это World DECLARE 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;
}
, объявляю пользователя
, 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;
};
вы не могут сделать это Другой путь вокруг: Как уже упоминалось, член класса должен иметь определение. (Причина в том, что компилятор должен знать, сколько памяти занимает пользователя
, и узнать, что ему нужно знать размер своих членов.) Если бы вы сказали:
class MyMessageBox;
class User
{
public:
// size not available! it's an incomplete type
MyMessageBox dataMsgBox;
};
это будет T работать, так как это еще не знает размера.
На боковом примечании эта функция:
void sendMessage(Message *msg, User *recvr);
, вероятно, не следует принимать ни одного из них по указателю. Вы не можете отправить сообщение без сообщения, и не сможете отправить сообщение без пользователей, чтобы отправить его. И оба этих ситуации выражают, передавая нулю в качестве аргумента для любого параметра (NULL - это совершенно допустимое значение указателя!)
, скорее, используйте ссылку (возможно, const):
void sendMessage(const Message& msg, User& recvr);
Вам необходимо определить MyMessageBox перед пользователем - потому что пользователь включает в себя объект MyMessageBox значение (и поэтому компилятор должен знать его размер).
Также вам понадобится World DECLARE Пользователь Befor MyMessagebox - потому что MyMessageBox включает в себя элемент пользователя *
Вы должны объявить прототип перед его использованием:
class User;
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message> *dataMessageList;
};
class User
{
public:
MyMessageBox dataMsgBox;
};
Редактировать : обменял типы
Компиляторы C ++ обрабатывают свой вход один раз. Каждый класс, который вы используете, должен быть определен первым. Вы используете MyMessageBox
, прежде чем определить его. В этом случае вы можете просто поменять два определения класса.