Eu tenho duas classes declaradas como abaixo:
class User
{
public:
MyMessageBox dataMsgBox;
};
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message> *dataMessageList;
};
Quando tento compilá-lo usando o gcc, ocorre o seguinte erro:
MyMessageBox não nomeia um tipo
g++
e nãogcc
Respostas:
Quando o compilador compila a classe
User
e chega àMyMessageBox
linha,MyMessageBox
ainda não foi definido. O compilador não tem ideiaMyMessageBox
, portanto, não pode entender o significado do seu aluno.Você precisa ter certeza de que
MyMessageBox
está definido antes de usá-lo como membro. Isso é resolvido revertendo a ordem de definição. No entanto, você tem uma dependência cíclica: se você se moverMyMessageBox
acimaUser
, na definição doMyMessageBox
nomeUser
não será definido!O que você pode fazer é declarar adiante
User
; ou seja, declare-o, mas não o defina. Durante a compilação, um tipo declarado mas não definido é chamado de tipo incompleto . Considere o exemplo mais simples:Ao declarar adiante
User
,MyMessageBox
ainda é possível formar um ponteiro ou uma referência a ele:Você não pode fazer o contrário: como mencionado, um aluno precisa ter uma definição. (O motivo é que o compilador precisa saber quanta memória
User
ocupa e saber que precisa saber o tamanho de seus membros.) Se você disser:Não funcionaria, pois ainda não sabe o tamanho.
Em uma nota lateral, esta função:
Provavelmente não deve pegar nenhum deles por ponteiro. Você não pode enviar uma mensagem sem uma mensagem, nem pode enviar uma mensagem sem um usuário para enviá-la. E ambas as situações são expressáveis passando null como argumento para qualquer parâmetro (null é um valor de ponteiro perfeitamente válido!)
Em vez disso, use uma referência (possivelmente const):
fonte
MyMessageBox
seria suficiente. E seMyMessageBox
tivesse uma variável do tipoUser
também - isso seria um impasse?User
que teria umMessageBox
que teria umUser
, que teria umMessageBox
que teria umUser
, que teria umMessageBox
que teria umUser
, que teria umMessageBox
que teria umUser
...fonte
Os compiladores C ++ processam suas entradas uma vez. Cada classe que você usa deve ter sido definida primeiro. Você usa
MyMessageBox
antes de defini-lo. Nesse caso, você pode simplesmente trocar as duas definições de classe.fonte
MyMessageBox
temUser
tipo nele de declaração de método.User
. Distinção importante, porque isso significa que o usuário da classe precisa ser declarado apenas nesse ponto, não definido . Mas veja o extenso post de GMan.User
tipo ainda não está declarado.Você precisa definir MyMessageBox antes do Usuário - porque o Usuário inclui o objeto MyMessageBox por valor (e, portanto, o compilador deve saber seu tamanho).
Além disso, você precisará encaminhar a declaração de Usuário para MyMessageBox - porque MyMessageBox inclui membro do tipo Usuário *.
fonte
Em uma nota relacionada, se você tivesse:
Então isso também funcionaria, porque o usuário está definido no MyMessageBox como um ponteiro
fonte
Você deve declarar o protótipo antes de usá-lo:
editar : Trocou os tipos
fonte
É sempre incentivado em C ++ que você tenha uma classe por arquivo de cabeçalho; veja esta discussão no SO [ 1 ]. A resposta GManNickG diz por que isso acontece. Mas a melhor maneira de resolver isso é colocar a
User
classe em um arquivo de cabeçalho (User.h
) e aMyMessageBox
classe em outro arquivo de cabeçalho (MyMessageBox.h
). EntãoUser.h
você incluiMyMessageBox.h
eMyMessageBox.h
incluiUser.h
. Não esqueça de "incluir gaurds" [ 2 ] para que seu código seja compilado com sucesso.fonte