我试图用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.h
或GraphicsManager.cpp
的开头放置了一个前向声明,Visual Studio会告诉我不允许使用不完整的类型。
这让我头疼了好几个星期。我之前用Java制作过游戏,并且接受了这种模式。那我该怎么做呢?如果在C ++中无法实现这种结构,你还有其他建议吗?
答案 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标题中,因此两个标题都不会相互包含在一起。