当编译器编译类User 并到达MyMessageBox 行时,MyMessageBox 尚未定义。编译器不知道MyMessageBox 的存在,所以无法理解你的类成员的含义。
您需要确保在将MyMessageBox 用作成员之前定义了它。这可以通过颠倒定义顺序来解决。但是,您有一个循环依赖:如果您将MyMessageBox 移动到User 上方,那么在MyMessageBox 的定义中将不会定义名称User!
你可以做的是转发声明 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;
}
通过前向声明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;
};
您不能反过来这样做:如前所述,类成员需要有一个定义。 (原因是编译器需要知道User 占用了多少内存,并且需要知道它的成员的大小。)如果你说:
class MyMessageBox;
class User
{
public:
// size not available! it's an incomplete type
MyMessageBox dataMsgBox;
};
它不起作用,因为它还不知道大小。
顺便说一句,这个函数:
void sendMessage(Message *msg, User *recvr);
可能不应该通过指针获取其中任何一个。你不能在没有消息的情况下发送消息,也不能在没有用户的情况下发送消息。这两种情况都可以通过将 null 作为参数传递给任一参数来表达(null 是一个完全有效的指针值!)
而是使用引用(可能是 const):
void sendMessage(const Message& msg, User& recvr);