我的具体问题是,在C++中实现单例类时,以下两种代码在性能、副作用或其他方面是否有实质性差异:
class singleton
{
// ...
static singleton& getInstance()
{
// allocating on heap
static singleton* pInstance = new singleton();
return *pInstance;
}
// ...
};
和这个:
class singleton
{
// ...
static singleton& getInstance()
{
// using static variable
static singleton instance;
return instance;
}
// ...
};
(Note that在基于堆的实现中取消引用不应影响性能,因为据我所知,取消引用不会生成任何额外的机器代码。这似乎只是一种从指针中区分出语法的问题。) 更新: 我收到了一些有趣的答案和评论,我在这里尝试总结它们。(对于那些感兴趣的人,建议阅读详细的答案。):
- 在使用静态局部变量的单例模式中,类析构函数会在进程终止时自动调用,而在动态分配的情况下,您必须以某种方式在某个时间管理对象的销毁,例如使用智能指针:
static singleton& getInstance() {
static std::auto_ptr<singleton> instance (new singleton());
return *instance.get();
}
使用动态分配的单例比静态单例变量更加“懒惰”,因为在后一种情况下,单例对象所需的内存在进程启动时(作为加载程序所需的整个内存的一部分)被预留,并且只有在调用
getInstance()
时才会延迟调用单例构造函数。当sizeof(singleton)
很大时,这可能很重要。C++11中两者都是线程安全的。但对于早期版本的C ++,具体实现可能不同。
动态分配案例使用一级间接访问单例对象,而在静态单例对象案例中,在编译时确定并硬编码对象的直接地址。