这个单例实现有问题吗
Is there an issue with this singleton implementation?
我通常习惯于用这种方式实现单例模式,因为它非常容易:
class MyClass
{
public:
MyClass* GetInstance()
{
static MyClass instance;
return &instance;
}
private:
//Disallow copy construction, copy assignment, and external
//default construction.
};
这似乎比创建静态实例指针、在源文件中初始化它以及在带有保护的实例函数中使用动态内存分配要容易得多。
有没有我没有看到的缺点?对我来说,它看起来是线程安全的,因为我认为第一个到达第一行的线程会导致实例化,而且它看起来很好,很简洁。我想肯定有一个问题我没有看到,因为这并不常见-我想在继续使用它之前得到一些反馈
这不是一个固有的线程安全解决方案:在构造实例时,另一个线程可以抢占并尝试获取实例,从而导致双实例或使用未构造的实例。
这是由几个编译器通过添加一个保护来处理的(在gcc中,我认为有一个标志可以禁用它),因为没有办法用用户定义的互斥来保护它。
缺点是无法控制对象何时被销毁。如果其他静态对象试图从其析构函数访问它,这将是一个问题。
一个兼容C++11的编译器必须以线程安全的方式实现这一点;然而,较旧的编译器可能不会。如果您有疑问,并且不特别希望延迟初始化,可以在启动任何线程之前通过调用访问器来强制创建对象。
接口中有两个问题:
- 您应该返回一个引用
- 您应该将析构函数或
delete
运算符设为private
此外,在该类被销毁后,尝试使用该类的风险很小。
关于您的多线程问题(我想还有初始化):它在C++11中很好,而且在好的C++编译器上已经好了很长一段时间。
除了在多线程场景中-没有。好吧,让我限定一下,构建是懒惰的(所以第一个调用可能会命中)和破坏-好吧,不能保证(除了它会在某个时候)
一般来说,方法中局部变量的限定符static
不能保证只创建一次变量。如果该方法由不同的线程调用,那么它可以为每个线程创建一次,因为很多线程都调用了它。不应该将它与类的静态成员混淆,后者在程序启动前创建一次。局部静态变量的线程安全性取决于c++的特殊实现。有用的链接:函数静态变量在GCC中是线程安全的吗?
希望能有所帮助。
- 我似乎对if/else的基本语句有问题:/
- 我在范围内未声明的错误类有问题
- 我的C++语言蛮力算法有问题
- 我关于函数"Assert"的C++代码有问题
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- C++类中的友元函数有问题?
- 是否有可能实现O(N)时间和O(1)空间解决方案,以实现C++中的字符串循环移位
- 我对数组即 0x6dfe78 有问题
- 我对 std::unique(算法)C++有问题
- 使用 fstream 库并在屏幕上打印的文件有问题?
- 这个模板为什么有问题?如何正确编译
- 我对 MyGraph 属性顶点名称和边权重有问题
- delete[]有问题,如何部分删除内存
- 在C++中使用exit()退出程序有问题吗
- 跳转到if(false)块有问题吗
- 虚拟 CTOR 的克隆函数实现是否有问题
- 拉盖尔插值算法,我的实现有问题
- Gale Shapley算法的实现有问题
- 堆栈的这个实现看起来有问题,但它运行良好
- 这个单例实现有问题吗