C++ 使用单例和子类的循环包含
在做我的一个小游戏时,我遇到了一个循环依赖相关的问题 假设我使用2个类和一个助手名称空间(都包括guarded),其中Base是主游戏类,Player是Player对象和Entity的子对象,helper是负责处理平铺冲突的函数名称空间: 当我试图编译代码时,Player在base.h中没有被识别为类型说明符,我还得到了一个未知的覆盖说明符。当我向前宣布球员时,它是未定义的,尽管我包括球员.h。 我一直在互联网上寻找解决方案,但没有一个典型的循环包含解决方案是适用的。如上所述,我尝试了各种前向声明的组合,但它只改变了错误的类型 我想知道是否有人能注意到下面代码中的任何缺陷 (请注意,我将所有函数实现放在标题中只是为了演示,它们有自己的小cpp文件) base.hC++ 使用单例和子类的循环包含,c++,inheritance,singleton,circular-dependency,C++,Inheritance,Singleton,Circular Dependency,在做我的一个小游戏时,我遇到了一个循环依赖相关的问题 假设我使用2个类和一个助手名称空间(都包括guarded),其中Base是主游戏类,Player是Player对象和Entity的子对象,helper是负责处理平铺冲突的函数名称空间: 当我试图编译代码时,Player在base.h中没有被识别为类型说明符,我还得到了一个未知的覆盖说明符。当我向前宣布球员时,它是未定义的,尽管我包括球员.h。 我一直在互联网上寻找解决方案,但没有一个典型的循环包含解决方案是适用的。如上所述,我尝试了各种前向声
#include "player.h"
#include "level.h"
class Base{
static Base& instance()
{
static Base base;
return base;
}
Player player;
Level level;
}
实体.h
class Entity{
vec2 velocity; //Assume we are using the glm library
vec2 position;
virtual void update()
{
}
}
player.h
#include "helper.h"
#include "entity.h"
class Player:public Entity{
void update()
{
velocity=helper::tileCollision(velocity);
//Update position and stuff
}
}
助手
#include "level.h"
#include "base.h"
namespace helper{
vec2 tileCollision(vec2 velocity)
{
Level& level = Game::instance().level;
//Pop some fancy tile collision math in here
return vec2(0);
}
}
首先,请不要在头中编写函数的实现,除非它不是内联的或模板的 请尝试以下操作: base.h
#include <memory>
class Player;
class Level;
class Base {
public:
static Base& instance();
private:
Base();
unique_ptr<Player> player;
unique_ptr<Level> level;
}
#包括
班级运动员;
班级层面;
阶级基础{
公众:
静态基&实例();
私人:
Base();
独特的ptr播放器;
独特的ptr水平;
}
base.cpp
#include "base.h"
#include "player.h"
#include "level.h"
Base::Base() : Player(make_unique<Player>()), Level(make_unique<Level>())
{
}
static Base& Base::instance()
{
static Base base;
return base;
}
#包括“base.h”
#包括“player.h”
#包括“h级”
Base::Base():播放器(使_唯一()),级别(使_唯一())
{
}
静态基&Base::instance()
{
静基座;
返回基地;
}
你应该注意以下几点:
您只显示了代码的一些片段,并附带了不合适的描述(转发声明在哪里?)并且留给我们太多的幻想。改为创建一个MCVE。“不要在头中编写代码”-也许更好的表达方式是“不要在头中编写函数的实现”:@Alex我觉得在这个示例中添加cpp文件是不必要的,这是完全独立的。但是,尽管这是一个有效的解决方案,但我不理解为什么没有合适的方法让一个单例的常规值成员(Base::instance().player类型)使用一个助手名称空间(helper),使用同一单例的另一个成员(Base::instance().level)。你愿意解释一下吗?