Rak*_*h K 117 c++ windows types
我有两个类声明如下:
class User
{
public:
MyMessageBox dataMsgBox;
};
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message> *dataMessageList;
};
Run Code Online (Sandbox Code Playgroud)
当我尝试使用gcc编译它时,它会给出以下错误:
MyMessageBox没有命名类型
GMa*_*ckG 192
当编译器编译类User并到达该MyMessageBox行时,MyMessageBox尚未定义.编译器不知道MyMessageBox存在,因此无法理解您的类成员的含义.
在将其用作成员之前,您需要确保MyMessageBox已定义.这可以通过颠倒定义顺序来解决.但是,你有一个循环依赖:如果你移动到上面,那么在名称的定义中将不会被定义!MyMessageBoxUserMyMessageBoxUser
你可以做的是向前宣布 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;
}
Run Code Online (Sandbox Code Playgroud)
通过前向声明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;
};
Run Code Online (Sandbox Code Playgroud)
你不能反过来这样做:如上所述,类成员需要有一个定义.(原因是编译器需要知道User占用了多少内存,并且知道它需要知道其成员的大小.)如果你要说:
class MyMessageBox;
class User
{
public:
// size not available! it's an incomplete type
MyMessageBox dataMsgBox;
};
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为它还不知道尺寸.
另外,这个功能:
void sendMessage(Message *msg, User *recvr);
Run Code Online (Sandbox Code Playgroud)
可能不应该通过指针采取其中任何一个.您无法在没有消息的情况下发送消息,也无法在没有用户发送消息的情况下发送消息.并且这两种情况都可以通过将null作为参数传递给任一参数来表达(null是一个完全有效的指针值!)
相反,使用引用(可能是const):
void sendMessage(const Message& msg, User& recvr);
Run Code Online (Sandbox Code Playgroud)
就我而言,事实证明这个非常无信息的错误是由循环依赖引起的。代替
// A.hpp
#include "B.hpp"
class A {
B b;
}
// B.hpp
#include "A.hpp"
class B {
A a;
}
Run Code Online (Sandbox Code Playgroud)
我将第二个文件更改为
// B.hpp
class A;
class B {
A a;
}
Run Code Online (Sandbox Code Playgroud)
...所有的编译器错误,以及我的 IDE 中突然缺少语法突出显示的问题都消失了。
我确实需要稍后#include "A.hpp"在文件顶部放置 a B.cpp,但这很好,因为在这种情况下不存在循环依赖 ( B.cpp -> A.hpp -> B.hpp -> /)。