C++单例模式下Game与Phase类的循环依赖编译问题
C++单例Game与Phase类编译问题解决方案
解决std::unique_ptr对不完整类型Phase的编译错误
std::unique_ptr的析构逻辑依赖类型的完整定义,直接在Game.hpp中用前向声明的Phase配合unique_ptr会触发编译错误。解决步骤:
- 在
Game.hpp中仅前向声明Phase,手动声明析构函数接口,将析构函数的实现移到Game.cpp中。 - 在
Game.cpp中包含Phase.hpp,让编译器拿到Phase的完整类型,确保unique_ptr能正常析构。
示例代码:
Game.hpp
#pragma once #include <memory> // 前向声明Phase class Phase; class Game { private: Game() = default; static Game* instance; std::unique_ptr<Phase> currentPhase; public: static Game& getInstance(); // 仅声明析构函数,不实现 ~Game(); // 其他成员声明 };
Game.cpp
#include "Game.hpp" #include "Phase.hpp" // 引入Phase完整定义 Game* Game::instance = nullptr; Game& Game::getInstance() { if (!instance) { instance = new Game(); } return *instance; } // 在这里实现析构函数,此时Phase是完整类型 Game::~Game() = default;
解决Phase构造函数调用Game::getInstance()未声明的错误
前向声明Game无法访问其静态成员函数,必须在Phase.hpp中包含Game.hpp,结合上面的析构分离方案,不会触发循环依赖问题:
Phase.hpp
#pragma once #include "Game.hpp" // 直接引入Game的完整定义 class Phase { protected: Game& game_; // 抽象基类构造函数,初始化Game引用 Phase() : game_(Game::getInstance()) {} public: virtual void update() = 0; // 纯虚函数,标记为抽象基类 virtual ~Phase() = default; };
抽象基类Phase的补充说明
- Phase作为抽象基类,无需单独的
Phase.cpp文件,因为纯虚函数不需要实现,析构函数已声明为默认实现。 - 子类需单独创建
.hpp和.cpp文件,在子类cpp中包含Phase.hpp,实现纯虚函数即可。
内容的提问来源于stack exchange,提问作者cozycoder
相关产品推荐
相关产品推荐

