我正在构建一个俄罗斯方块,并试图避免指针。在下面的代码中,我尝试在另一个类" TetrisWindow" 中定义类" ButtonQuit" 的实例,这两个类都是互相使用'方法。我一直收到错误:
‘ButtonQuit’ does not name a type: ButtonQuit btnQuit;
或:
field ‘btnQuit’ has incomplete type: ButtonQuit btnQuit;
我知道有一个循环包含,但我无法弄清楚如何解决这个问题。我已经尝试过宣布 ButtonQuit ,但它无法正常工作。
( WindowSDL 只是一个包含所有图形功能的类,除了SDL之外,它没有包含它。)
这是我的代码(当我编译这个时,我得到"没有命名类型"错误):
BUTTONQUIT.HPP:
#ifndef __BUTTONQUIT__
#define __BUTTONQUIT__
#include <TetrisWindow.hpp>
class ButtonQuit{
private:
int x,y;
TetrisWindow win;
public:
ButtonQuit (TetrisWindow, int, int);
~ButtonQuit();
void print(void);
void action(void);
bool clicked(int, int);
};
#endif
TETRISWINDOW.HPP:
#ifndef __TETRISWINDOW__
#define __TETRISWINDOW__
#include <cstdint>
#include <string>
#include <vector>
#include <WindowSDL.hpp>
#include <ButtonQuit.hpp>
class TetrisWindow: public WindowSDL{
protected:
ButtonQuit btnQuit;
void handleEvent(SDL_Event&);
void work(void);
public:
TetrisWindow();
TetrisWindow(uint16_t, uint16_t);
TetrisWindow(const TetrisWindow& w);
~TetrisWindow();
void drawWindow(void);
};
#endif
答案 0 :(得分:2)
问题不在于您的情况下的循环包含,这是次要问题。
您应该考虑的第一个问题是TetrisWindow
有ButtonQuit
成员,而ButtonQuit
有TetrisWindow
成员。
这两个成员不是指针也不是引用,这意味着它们将以包含类的整个大小存储。这导致了一个不会结束的递归结构。
TetrisWindow
必须包含ButtonQuit
,其中必须包含TetrisWindow
,其中必须包含ButtonQuit
...
这里的解决方案是在相应的其他标头中转发声明这两个类,并使用指针/引用,例如:
// TetrisWindow.h
class ButtonQuit;
class TetrisWindow {
private:
ButtonQuit* button;
...
}
// ButtonQuit.h
class TetrisWindow;
class ButtonQuit {
private:
TetrisWindow* window;
...
}
现在您使用指针作为成员,因此编译器不必知道sizeof(ButtonQuit)
或sizeof(TetrisWindow)
的定义,因为指针始终是指针。这样您就可以根本不包含其他类的标题,只要您没有尝试访问不完整类型的内联函数。
答案 1 :(得分:1)
您的班级TetrisWindow
由ButtonQuit
(以及一些会员功能)组成。此ButtonQuit
还有一个TetrisWindow
类型的成员(其成员类型为ButtonQuit
,其成员类型为TetrisWindow
....)。
有了这个看法,你就无法解决问题,两个人都是不可能的。
你需要的是某种“知道”而不是“由......组成”的关系。
通常这是通过指针完成的,因此让ButtonQuit
成员TetrisWindow* parent
可能是有意义的 - 这是一个非拥有指针,你可以声明你的TetrisWindow
例如作为具有自动存储持续时间的全局变量(这意味着不需要delete
)。
“知道”关系的另一个选择是引用,但需要在构造函数中设置引用 - 这意味着您需要在TetrisWindow
和{{1}之前构造ButtonQuit
在ButtonQuit
之前。