对于以下定义单身人士的方法,是否存在任何差异或具体建议?
在1中,单例对象是类私有静态,但在2中,它是一个静态文件。
注意:m_initedObj1就是为了表明该类有状态,而用例是多次调用这个singleton-> DoSomething(),而不需要再次初始化该对象。
1)
// header file
class Foo {
private:
static Foo* s_fooSingleton;
Foo();
Obj1 m_initedObj1;
public:
static Foo* Singleton();
static void ClearSingleton();
Bar DoSomething(...);
};
// cpp file
Foo* Foo::s_fooSingleton = nullptr;
Foo::Foo() { m_initedObj1 = InitObj1Somewhere(); }
/*static*/ Foo* Foo::Singleton()
{
if(!Foo::s_fooSingleton)
Foo::s_fooSingleton = new Foo();
return Foo::s_fooSingleton;
}
/*static*/ void Foo::ClearSingleton()
{
if(Foo::s_fooSingleton)
delete Foo::s_fooSingleton;
Foo::s_fooSingleton = nullptr;
}
Bar Foo::DoSomething(...) { // do something }
2)
// header file
class Foo {
private:
Foo();
Obj1 m_initedObj1;
public:
static Foo* Singleton();
static void ClearSingleton();
Bar DoSomething(...);
};
// cpp file
static Foo* s_fooSingleton = nullptr;
Foo::Foo() { m_initedObj1 = InitObj1Somewhere(); }
/*static*/ Foo* Foo::Singleton()
{
if(!s_fooSingleton)
s_fooSingleton = new Foo();
return s_fooSingleton;
}
/*static*/ void Foo::ClearSingleton()
{
if(s_fooSingleton)
delete s_fooSingleton;
s_fooSingleton = nullptr;
}
Bar Foo::DoSomething(...) { // do something }
答案 0 :(得分:2)
作为JerryGoyal states in the comments,在2)同一.cpp文件中的其他方法可以修改s_fooSingleton。
另一方面,它们不是线程安全的。如果您不介意清除(显式调用ClearSingleton()),请使用Scott Meyers'版本。 否则,请使用double checked locking版本。
在明确删除的情况下确保安全非常困难。在访问它之前,您始终必须检查它是否已被删除。如果它是一个多线程可执行文件,检查和使用它必须是原子的,因为它可以在检查后立即删除。
双重检查锁定可用于创建和删除单例,这可确保您一次只有一个实例。然而,它并不能确保对象确实存在,因为您可能会意外删除它。
如果没有引用,您可以使用智能指针来计算引用并删除它。
甚至更好,请参阅此答案https://stackoverflow.com/a/15733545/1632887。
如果我是你,我就不会明确删除它!
答案 1 :(得分:0)
也许这会让你更满意:
class MyClass1 {
private:
MyClass1(){}
public:
MyClass1& Instance() {
static MyClass1 theSingleInstance;
return theSingleInstance;
}
};
class MyClass2 {
private:
MyClass2() {}
public:
MyClass2* Instance() {
static MyClass2* theSingleInstance = new MyClass2;
return theSingleInstance;
}
};
class MyClass3 {
private:
MyClass3() {}
public:
MyClass3* Instance() {
static MyClass3 theSingleInstance;
return &theSingleInstance;
}
};