如何用静态指针简化单例类GetInstance调用并避免重定义?
简化单例类全局调用的可行方案
通常调用单例类的成员时,我们需要编写如下代码:
SomeSingleton::GetInstance().someVariable
想要找到一种全局可用的简化写法,且希望将实现放在单例类自身的头文件和源文件中。
尝试过的错误实现
头文件(SomeSingleton.hpp)
class SomeSingleton { //... static SomeSingleton& GetInstance(); }; SomeSingleton& (*INSTANCE)();
源文件(SomeSingleton.cpp)
SomeSingleton& (* INSTANCE)() = SomeSingleton::GetInstance;
这段代码会被编译器判定为重定义,无法正常编译。若将声明与定义写在同一行可以运行,但无法放在全局引用的头文件中。单独给已声明的INSTANCE赋值,和在每个使用文件中定义INSTANCE一样繁琐。
临时但不理想的方案
在每个使用该单例的文件中添加如下代码:
static SomeSingleton& (*INSTANCE)() = SomeSingleton::GetInstance;
之后用INSTANCE()替代SomeSingleton::GetInstance()。这种方法虽然可行,但不够优雅,且从设计角度看,将单例的获取函数赋值给另一个静态变量的合理性也存在疑问。
可行的解决思路
方案1:使用全局inline变量(C++17及以上)
在头文件中直接定义全局inline变量,指向单例实例:
class SomeSingleton { //... static SomeSingleton& GetInstance(); }; inline SomeSingleton& INSTANCE = SomeSingleton::GetInstance();
这样任何包含该头文件的地方都可以直接使用INSTANCE.someVariable,inline关键字保证不会出现重定义问题,且仅需在头文件中声明一次,无需源文件额外处理。
方案2:宏定义(简单直接但不推荐)
若项目允许使用宏,可在头文件中添加:
#define INSTANCE SomeSingleton::GetInstance()
之后直接编写INSTANCE.someVariable即可。缺点是宏无类型检查,可能引发意外问题,不符合现代C++编码风格。
方案3:封装为全局函数
在头文件中声明全局函数,源文件中实现:
头文件
class SomeSingleton { //... static SomeSingleton& GetInstance(); }; SomeSingleton& INSTANCE();
源文件
SomeSingleton& INSTANCE() { return SomeSingleton::GetInstance(); }
调用时使用INSTANCE().someVariable,与原写法逻辑一致但更简洁,且不存在重定义问题,符合类型安全要求。
方案4:将INSTANCE作为类的静态成员
直接在单例类中添加静态引用成员:
头文件
class SomeSingleton { //... static SomeSingleton& GetInstance(); static SomeSingleton& INSTANCE; };
源文件
SomeSingleton& SomeSingleton::INSTANCE = SomeSingleton::GetInstance();
调用时使用SomeSingleton::INSTANCE.someVariable,虽仍需书写类名,但比原写法简短,且逻辑统一,属于类的一部分。
内容的提问来源于stack exchange,提问作者Gyula Sámuel Karli
相关产品推荐
相关产品推荐

