當編譯器編譯類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);
也許不應該由指針採取這類原因。沒有消息就不能發送消息,也不能發送沒有用戶發送消息的消息。而這兩方面的情況是由空作爲參數傳遞給任一參數表達
相反,使用引用(可能是const的)(null是一個完全有效的指針值!):
void sendMessage(const Message& msg, User& recvr);
無盡的時間,我去這個錯誤,只是意識到由IDE生成的導入警衛重複 – Mazyod 2015-08-15 11:39:22
請注意,如果您將一個外部引用聲明放在.h/.hpp文件中也可以得到此錯誤在定義類之前,即使在.cpp文件中的.h/.hpp包含之後有實際的聲明。 – Owl 2016-03-19 20:01:41
@Mazyod。謝謝謝謝。我無法弄清楚是什麼造成了這個奇怪的錯誤。 – 2017-02-10 19:13:04