“不命名types”错误

我有两个类声明如下:

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

当我尝试使用gcc进行编译时,会出现以下错误:

MyMessageBox不会命名一个types

当编译器编译类User并到达MyMessageBox行时, MyMessageBox尚未定义。 编译器不知道MyMessageBox存在,所以不能理解你的类成员的含义。

使用MyMessageBox作为成员之前,您需要确保MyMessageBox已经被定义。 这是通过反转定义顺序来解决的。 然而,你有一个循环依赖:如果你移动MyMessageBox上面的User ,然后在MyMessageBox的定义名称User将不会被定义!

你可以做的是向前宣布 User ; 即声明它,但不要定义它。 在编译过程中,声明但未定义的types称为不完整types 。 考虑一个更简单的例子:

 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; } 

通过向前声明UserMyMessageBox仍然可以形成指针或对其的引用:

 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级成员需要有一个定义。 (原因是编译器需要知道User占用了多less内存,并知道它需要知道其成员的大小。)如果你要说:

 class MyMessageBox; class User { public: // size not available! it's an incomplete type MyMessageBox dataMsgBox; }; 

这是行不通的,因为它还不知道尺寸。


在一个侧面说明,这个function:

  void sendMessage(Message *msg, User *recvr); 

可能不应该采取任何一个指针。 没有消息就不能发送消息,也不能发送没有用户发送消息的消息。 这两种情况都可以通过将null作为parameter passing给任一参数来表示(null是一个完全有效的指针值!)

而是使用一个引用(可能是const):

  void sendMessage(const Message& msg, User& recvr); 
  1. 正向声明用户
  2. 在用户之前放置MyMessageBox的声明

C ++编译器处理一次input。 您使用的每个课程都必须先定义。 在定义之前使用MyMessageBox 。 在这种情况下,您可以简单地交换两个类的定义。

你需要在User之前定义MyMessageBox – 因为User 通过值包含了MyMessageBox 对象(所以编译器应该知道它的大小)。

您还需要转发声明用户为MyMessageBox – 因为MyMessageBox包含User *types的成员。

在一个相关的说明,如果你有:

  class User; // let the compiler know such a class will be defined class MyMessageBox { public: User* myUser; }; class User { public: // also ok, since it's now defined MyMessageBox dataMsgBox; }; 

那么这也将工作,因为用户在MyMessageBox中定义为一个指针

在使用之前,您必须先声明原型:

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

编辑 :交换的types

在C ++中总是鼓励每个头文件有一个类,请参阅SO [ 1 ]中的讨论。 GManNickG的答案告诉为什么会发生这种情况。 但解决这个问题的最好方法是将User类放在一个头文件( User.h )中,将MyMessageBox类放在另一个头文件( MyMessageBox.h )中。 然后在你的User.h包含MyMessageBox.h ,在MyMessageBox.h包含User.h 不要忘记“包括gaurds”[ 2 ],以便您的代码编译成功。