c++类循环引用

c++ class circular reference?

本文关键字:引用 循环 c++      更新时间:2023-10-16

我正在制作一个小游戏引擎,但是我被一些东西卡住了。说明:我有两个班,cEntityObjectFactory:

<标题> cEntity h1> ObjectFactory h1> 在我在cEntity构造器中添加新的cEnityObjectFactory,但面临与循环引用相关的错误:对于使用ObjectFactor::addEntity(),我需要在cEntity类中定义ObjectFactory.h,但它创建了一个循环引用。

考虑到你对问题的描述,我认为你的代码可能存在潜在的架构问题。

你的ObjectFactory应该处理cEntities,这反过来应该不知道"上面的级别"。从你遇到的问题的描述来看,它暗示你不确定哪个类负责哪个工作。

你的cEntitys应该公开一个接口(即类中标记为"public"的所有东西),其他代码位与之交互。您的ObjectFactory(如果执行此工作,它的命名有点糟糕,但无论如何)应该依次使用该接口。开发者不应该关心谁在使用界面:他们有一项工作要做,他们就去做。ObjectFactory应该有一项工作需要它保存一个centity列表。当您在其他地方使用std::string时,您不会编辑它:为什么您的类有任何不同?


话虽这么说,解决循环依赖有两个部分(除了"首先不要创建具有循环依赖的代码"之外)——参见这个答案的第一部分。在我看来,这是避免这类问题的最好方法。

1)包括警卫。对每个头文件(.h)执行如下操作:

#ifndef CENTITY_H
#define CENTITY_H
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
#endif

  • 第一次包含文件时,没有定义CENTITY_H。因此,ifndef宏为真,并移动到下一行(定义CENTITY_H),然后移动到标题的其余部分。
  • 第二次(以及以后的所有时间),CENTITY_H被定义,因此ifndef宏直接跳到endif,跳过您的标题。随后,头代码只会在编译后的程序中出现一次。如果您想了解更多细节,请尝试查看链接器进程。

2)类的前向声明。

如果ClassA需要一个ClassB类型的成员,而ClassB需要一个ClassA类型的成员,那么你就会遇到一个问题:两个类都不知道它需要分配多少内存,因为它依赖于包含它自己的另一个类。

解决方案是您有一个指向另一个类的指针。指针是编译器已知的固定大小,所以我们没有问题。但是,我们确实需要告诉编译器,如果它遇到一个我们之前还没有定义的符号(类名),不要太担心,所以我们在开始使用它之前只添加class Whatever;

在您的例子中,将cEntity实例更改为指针,并在开始时向前声明该类。您现在可以在cEntity中自由地使用ObjectFactory了。

#include "cEntity.h"
#include <vector>
class cEntity;  // Compiler knows that we'll totally define this later, if we haven't already
class ObjectFactory
{
static std::vector<cEntity*> *entityList;  // vector of pointers
static int i, j;
public:
static void addEntity(cEntity* entity) {  
entityList->push_back(entity);
}
// Equally valid would be:
// static void addEntity(cEntity entity) {
// entityList->push_back(&entity);}
// (in both cases, you're pushing an address onto the vector.)
// Function arguments don't matter when the class is trying to work out how big it is in memory
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity*> *ObjectFactory::entityList = new std::vector<cEntity*>();