如何调整程序架构以在自定义类中调用Base类的静态成员变量
问题解决方法
一、快速修复编译错误
你遇到的「未知标识符」报错本质是你实现的GameObject子类的代码文件没有引入对应声明,按以下步骤处理即可:
- 首先在你编写的新对象类的
.h和.cpp文件顶部引入#include "Base.h"
从你给出的代码可以看出项目里已经通过宏或者typedef给Base类定义了别名B,只要引入Base头文件,就能正常访问B::cur_p这类静态成员。 - 额外修复静态成员重复定义隐患:你现在把所有静态成员的定义写在了Base.h末尾,这会导致多个cpp文件引入Base.h时出现链接重复定义错误。请把以下这些静态成员定义全部移到新建的
Base.cpp文件中,Base.h只保留类内的静态成员声明即可:
sf::RenderWindow B::wnd; Texture B::texture; Font B::font; Audio B::audio; sf::Event B::event; int B::scr_w; int B::scr_h; v2f B::cur_p; v2f B::cur_p_wnd; float B::time; sf::Clock B::clock; vector<unique_ptr<GameObject>> B::objects;
二、架构优化建议
当前的全静态Base类本质是变相的全局变量集合,后续维护会出现生命周期不可控、无法单元测试、多场景切换逻辑难写等问题,建议按以下方向调整:
- 把Base改为上下文类,移除所有静态修饰,构造函数直接做初始化,不需要靠传"init"字符串的奇怪逻辑控制。
- 采用依赖注入模式,修改GameObject的三个核心方法签名:
遍历调用对象方法时把当前上下文实例传进去,完全不需要全局变量,后续要做单测直接构造测试用的上下文传参即可。virtual void Update(const BaseContext& ctx) = 0; virtual void Action(const BaseContext& ctx) = 0; virtual void Draw(sf::RenderWindow& wnd, const BaseContext& ctx) = 0; - 将
objects对象容器从Base类移到Game类中,Base类只负责存储窗口、输入、时间这类全局上下文数据,对象管理属于游戏逻辑层职责,不要和基础上下文耦合。
内容的提问来源于stack exchange,提问作者Natriy
相关产品推荐
相关产品推荐

