[英]"X does not name a type" error in C++
我有两个类声明如下:
class User
{
public:
MyMessageBox dataMsgBox;
};
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message> *dataMessageList;
};
当我尝试使用 gcc 编译它时,出现以下错误:
MyMessageBox 没有命名类型
当编译器编译类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);
C ++编译器处理它们的输入一次。 您使用的每个类必须首先定义。 在定义之前使用MyMessageBox
。 在这种情况下,您可以简单地交换两个类定义。
您需要在User之前定义MyMessageBox - 因为User 按值包含MyMessageBox 的对象(因此编译器应该知道它的大小)。
此外,您还需要转发声明 User befor MyMessageBox - 因为MyMessageBox包含User *类型的成员。
在相关的说明中,如果您有:
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;
};
然后这也可以,因为User在MyMessageBox中被定义为指针
您必须在使用之前声明原型:
class User;
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message> *dataMessageList;
};
class User
{
public:
MyMessageBox dataMsgBox;
};
编辑 :交换类型
在我的例子中,事实证明这个非常无意义的错误是由循环依赖引起的。 代替
// A.hpp
#include "B.hpp"
class A {
B b;
}
// B.hpp
#include "A.hpp"
class B {
A a;
}
我将第二个文件更改为
// B.hpp
class A;
class B {
A a;
}
...所有编译器错误,以及我的 IDE 中突然缺少语法突出显示,都消失了。
稍后我确实需要在B.cpp
文件的顶部放置一个#include "A.hpp"
,但这很好,因为在这种情况下没有循环依赖( B.cpp -> A.hpp -> B.hpp -> /
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.