“X не называет тип” ошибкой в C++

У меня есть два класса, объявил как указано ниже:

class User
{
public:
  MyMessageBox dataMsgBox;
};

class MyMessageBox
{
public:
  void sendMessage(Message *msg, User *recvr);
  Message receiveMessage();
  vector<Message> *dataMessageList;
};

Когда я пытаюсь скомпилировать его с помощью gcc, это дает следующую ошибку:

MyMessageBox не называет тип

115
задан jww 13 March 2018 в 18:26
поделиться

5 ответов

Когда компилятор компиляторует пользователь класса и попадает в строку 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);
191
ответ дан 24 November 2019 в 02:26
поделиться

Вам необходимо определить MyMessageBox перед пользователем - потому что пользователь включает в себя объект MyMessageBox значение (и поэтому компилятор должен знать его размер).

Также вам понадобится World DECLARE Пользователь Befor MyMessagebox - потому что MyMessageBox включает в себя элемент пользователя *

2
ответ дан 24 November 2019 в 02:26
поделиться
121 --- 2424879-
  1. World Opplare User
  2. Положите декларацию MyMessageBox перед пользователем
8
ответ дан 24 November 2019 в 02:26
поделиться

Вы должны объявить прототип перед его использованием:

class User;

class MyMessageBox
{
public:
 void sendMessage(Message *msg, User *recvr);
 Message receiveMessage();
 vector<Message> *dataMessageList;
};

class User
{
public:
 MyMessageBox dataMsgBox;
};

Редактировать : обменял типы

0
ответ дан 24 November 2019 в 02:26
поделиться

Компиляторы C ++ обрабатывают свой вход один раз. Каждый класс, который вы используете, должен быть определен первым. Вы используете MyMessageBox , прежде чем определить его. В этом случае вы можете просто поменять два определения класса.

2
ответ дан 24 November 2019 в 02:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: