单例文件静态与类私有静态

时间:2017-04-06 05:26:56

标签: c++

对于以下定义单身人士的方法,是否存在任何差异或具体建议?

在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 }

2 个答案:

答案 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;
    }
};