我收到此头文件的编译错误:
#ifndef GAME1_H
#define GAME1_H
#include "GLGraphics.h"
#include "DrawBatch.h"
class GameComponent;
class Game1 {
private:
GLGraphics graphics;
GameComponent components;
void updateDelegates();
void Run();
};
class GameComponent {
private:
static int index;
protected:
Game1 game;
public:
GameComponent();
GameComponent(Game1 game);
void Update(int);
void Dispose();
};
class DrawableGameComponent: public GameComponent
{
private:
GLGraphics graphics;
DrawBatch drawBatch;
public:
DrawableGameComponent();
DrawableGameComponent(Game1);
void Draw();
};
#endif
我看到的问题是Game1需要GameComponent的完整定义,而GameComponent需要Game1的完整定义。我在单独的标题中有这些太麻烦了,所以这就是他们在一起的原因。如果没有完全改变其中一个类的实现,我有什么方法可以做到这一点吗?
谢谢!
答案 0 :(得分:10)
在这里考虑一下计算机的内存。
class B;
class A {
byte aa;
B ab;
};
class B {
byte bb;
A ba;
};
A x;
现在编译器需要回答的问题是我应该为x
预留多少空间?
我们来看看。 x
的第一个字节是byte aa;
。很容易。这是1个字节
接下来是B ab;
。让我们看看那里有什么
x.ab
的第一个字节是byte bb;
。到目前为止,这是x
的2个字节
接下来是A ba;
。让我们看看那里有什么
x.ab.ba
的第一个字节是byte aa;
。到目前为止,这是x
的3个字节
无穷无尽等等
x
有多大?正确的答案当然是*** OUT OF CHEESE ERROR ***
。
编译器实际上并不这样做,因为它知道它无法处理这种情况 - 因此语法首先不允许循环包含。
以下是此示例中x
的内容图:
Diagram http://i56.tinypic.com/28c0oiq.png
<强>更新强>
显然,我忘了在这里提供一个解决方案。现在您已经了解了问题所在,解决方案应该非常简单。使用指针。 要么使用从A
到B
的指针,要让B
包含A
,因为它已经存在,或副反之,或使用两个指针。然后,您将不会进行循环包含 - 如果B
不包含A
的副本,而只是指向它的指针,则会解决整个问题。
答案 1 :(得分:4)
要做你正在尝试的事情,你需要有一个指向你的某个类的指针,而不是将它作为成员。
例如:
class A;
class B;
class A {
B b;
};
class B {
A a;
};
这不起作用。它导致圆形结构。 A的构造函数将调用B的构造函数,它为A调用构造函数,依此类推。
相反,请尝试:
class A;
class B;
class A {
B *b;
};
class B {
A *a;
};
但是,有一句警告。如果你以这种方式设置某些东西,你的设计很有可能存在缺陷。你应该重新考虑如何解决问题。
答案 2 :(得分:1)
存在偏离主题的风险:您可以在C#中执行此操作,但除非嵌套成员全部按需加载,否则在首次实例化时会立即崩溃。