“不命名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; }
通过向前声明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; };
你不能这样做:如前所述,一个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);
- 正向声明用户
- 在用户之前放置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 ],以便您的代码编译成功。