我正在使用 boost 单例(来自序列化)。
例如,有一些类继承boost::serialization::singleton
。他们每个人在它的定义附近都有这样的定义(在 h 文件中):
#define appManager ApplicationManager::get_const_instance()
class ApplicationManager: public boost::serialization::singleton<ApplicationManager> { ... };
并且我必须在每次更新(将近 17 毫秒)时从该类调用一些方法,例如 200 次。所以代码是这样的:
for (int i=0; i < 200; ++i)
appManager.get_some_var();
我用 gprof
查看函数调用堆栈,每次都看到 boost::get_const_instance
调用。也许,在 Release模式下,编译器会对此进行优化?
我的想法是创建一些全局变量,例如:
ApplicationManager &handle = ApplicationManager::get_const_instance();
并且使用handle
,所以它不会每次都调用get_const_instnace
。是吗?
最佳答案
而不是使用 Singleton anti-pattern ,只是一个全局变量并完成它。它更诚实。
Singleton 的主要好处是当你想要惰性初始化时,或者比全局变量允许的更细粒度的初始化顺序控制。看起来这些事情中的任何一个都不是您关心的问题,所以只需使用全局变量即可。
就我个人而言,我认为使用全局变量或单例的设计几乎肯定是错误的。但是对于每个 h(is/er) 自己。
如果您一心想使用单例,您提出的性能问题很有趣,但可能不是问题,因为函数调用开销可能小于 100ns。正如所指出的,您应该配置文件。如果你真的很关心它,在循环之前存储一个对 Singleton 的本地引用:
ApplicationManager &myAppManager = appManager;
for (int i=0; i < 200; ++i)
myAppManager.get_some_var();
顺便说一句,以这种方式使用 #define
是一个严重的错误。几乎所有将预处理器用于除基于编译时标志的条件编译以外的任何事情的情况都可能是一种糟糕的使用。 Boost 确实广泛使用了预处理器,但主要是为了绕过 C++ 的限制。不要模仿它。
最后,该功能可能正在做一些重要的事情。 Singleton 的 get_instance
方法的作用之一是避免多个线程同时初始化同一个 Singleton。对于全局变量,这应该不是问题,因为它们应该在您启动任何线程之前进行初始化。
关于c++ - 静态对象和单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4472111/