循环依赖问题

时间:2014-08-15 03:08:39

标签: c++ circular-dependency

在尝试制作简单的游戏时,我遇到了循环依赖问题。 我在互联网上搜索并发现前向声明可以修复它,但是......我的两个类都依赖于静态值。

有没有简单的方法可以解决,也许是为了转发声明静态值,还是我必须重写游戏的核心?

2ND编辑:看起来我错了,即使删除了几乎所有内容后错误仍然存​​在:

main.cpp中:

#include "App.h"

//Start the app
int main(int argc, char* args[]){
    App App;

    return App.on_execute();
}

App.h:

#ifndef APP_H
#define APP_H
#include "Object.h"

class App
{
   public:

        //Runs when the program starts
        int on_execute();

};

#endif // APP_H

App.cpp:

#include "App.h"


int App::on_execute(){
    return 0;
}

Object.h:

#ifndef OBJECT_H
#define OBJECT_H
#include <string>
#include <vector>
#include <stdio.h>
#include <SDL.h>
#include <math.h>
#include "Entity.h"

class Object
{
    public:
        Object(int character, int x, int y, std::string name, SDL_Color color, bool blocks);

        //Object vector
        static std::vector<Object*> objects;
};

#endif // OBJECT_H

Object.cpp:

#include "Object.h"

std::vector<Object*> Object::objects;

Object::Object(int character, int x, int y, std::string name, SDL_Color color, bool blocks){
}

Entity.h:

#ifndef ENTITY_H
#define ENTITY_H
#include "Object.h"
#include <sdl.h>

class Entity : public Object
{
    public:
        Entity(int character, int x, int y, std::string name, SDL_Color color, bool blocks, int hp, int power, int defense);
};

#endif // ENTITY_H

Entity.cpp:

#include "Entity.h"

Entity::Entity(int character, int x, int y, std::string name, SDL_Color color, bool blocks, int hp, int power, int defense) : Object(character, x, y, name, color, blocks){
}

1 个答案:

答案 0 :(得分:0)

我认为代码的设计可能需要重新设计。

首先,我真的不鼓励你在可能的情况下使用非原始的,非平凡的类静态,无论是类静态还是全局静态。非平凡的静态类将在main之前有一个显式的构造函数调用,并且需要注册一个在main之后调用的破坏。这些东西的相对排序是不确定的。更糟糕的是,如果稍后你有一个库结构,使得来自同一.cpp文件的程序集出现两次,那么在构造对象的两个副本时会发生奇怪的事情,但同一个副本会被销毁两次。

其次,一些信息不清楚。例如,您声称Map类具有Map类型的静态成员。我真的不认为这是可能的;静态Map成员还将具有map类型的对象,依此类推。与Object中声明的Object向量类似。也许在这两种情况下你的意思是在文件Map.cpp或Object.cpp中,而不是字面上的类?

第三,明确前瞻性声明给你的是什么。它使编译意识到某些东西存在,仅此而已。它允许您拥有指向该类型的指针和引用。您无法创建对象,甚至无法声明前向声明类型的成员变量,因为编译器不知道前向声明对象的大小。您不能使用它的方法,因为编译器不知道它们存在。

第四,你根本没有谈论你的头文件。如果Map.h需要Object.h,它只是一个循环依赖,反之亦然。两个头文件不能相互包含。另一方面,实现在Map.cpp和Object.cpp中,这两个文件都可以包含Map.h和Object.h。但是,我个人更愿意避免相互依赖的课程。

我可能建议的是,地图应该拥有该地图上的对象。现在使用Map访问这个全局的模式并不是一个好的模式。而不是让对象成为全局对象,使std :: vector对象成为Map类的成员。请注意,如果您决定稍后使用多个地图,则效果会更好,每个地图都将拥有位于该地图上的对象。如果有多个Map,则当前设计不能很好地工作。

然后,您可以将move_to实现为不是Object的方法,而是实现Map。 Map :: move_to(i,dx,dy)移动第i个对象。