对象访问在C ++中包含它的对象

时间:2014-12-21 19:41:00

标签: c++ class include header-files circular-dependency

我试图用C ++创建游戏。 它有一个" Session"那种管理一切的类。它包含GraphicsManager,SoundManager和当前世界。它还包含一个指向其自身实例的静态指针。这样,我希望世界可用于GraphicsManager,以便可以渲染它,例如。

以下是我的代码的简化版本:

main.ccp

#pragma once
#include "Session.h"

int main() {
    Session::getSession()->run(); //Starts a new session and runs it
    return 0;
}

Session.h

#pragma once
#include "GraphicsManager.h"
#include "World.h"

class Session; //Forward declaration so it can have a pointer to itself

class Session {
private:
    Session();
    static Session* s;
    World* w; //Pointer because no world is loaded at the beginning of the program
    GraphicsManager gm; //Required right away
public:
    ~Session();
    void run(); //Actually launches the game after preparation; not further declared in this example
    World* getWorld(); //Returns the pointer to the current world
    static Session* getSession();
}

Session.cpp

#include "Session.h"

Session::Session(): gm(GraphicsManager()) {}

Session* Session::getSession() { //Return an instance of Session. If no instance exist yet, create one.
    if(s == NULL) s = new Session();
    return s;
}

World* Session::getWorld() {return w;} //Returns a pointer to the current world

GraphicsManager.h

#pragma once;

class GraphicsManager {
private:
    void render();
public:
    void run(); //Calls the render method repeatedly; no further declaration in this example
}

GraphicsManager.cpp

#include "GraphicsManager.h"

void GraphicsManger::render() {
    World* w = Session::getSession()->getWorld(); //Get pointer to current world so it can be rendered
}

渲染方法是我陷入困境的地方。如果我将#include "Session.h"放入GraphicsManager.h文件,它会给我一个错误,因为显然两个头文件不能相互包含。如果我在GraphicsManager.hGraphicsManager.cpp的开头放置了一个前向声明,Visual Studio会告诉我不允许使用不完整的类型。

这让我头疼了好几个星期。我之前用Java制作过游戏,并且接受了这种模式。那我该怎么做呢?如果在C ++中无法实现这种结构,你还有其他建议吗? Scheme

2 个答案:

答案 0 :(得分:1)

在GraphicsManager.cpp中,编译器需要知道Session,所以你必须#include "Session.h"顺便提一下包括GraphicsManager和World。

前向定义是不够的,因为编译器无法检查getSession()->getWorld()表达式的类型。

显然你的GraphicsManager.h不依赖于其他定义,所以这里不应该有问题。

答案 1 :(得分:1)

尝试将Session.h加入GraphicsManager.cpp

#include "Session.h"

void GraphicsManger::render() {
  World* w = Session::getSession()->getWorld(); //Get pointer to current world so it can be rendered
}

这样,GraphicsManager.cpp中的编译器可以看到Session类的defenition,因此它不会生成incomplite类型错误。另一方面,Session.h不包含在GraphicsManager标题中,因此两个标题都不会相互包含在一起。