C++ 为什么这个单例实现使用私有类(C+;+;)?

C++ 为什么这个单例实现使用私有类(C+;+;)?,c++,class,singleton,C++,Class,Singleton,因此,我正在使用供应商应用程序中的一些新代码,我观察到他们的一个库使用了单例模式。在那里,他们使用一个Helper来实例化singleton。为什么这是必要的 库头文件: Class LibExample { public: static LibExample* getInstance(); private: class Helper { public: Helper() { libExampleInstance = new L

因此,我正在使用供应商应用程序中的一些新代码,我观察到他们的一个库使用了单例模式。在那里,他们使用一个
Helper
来实例化singleton。为什么这是必要的

库头文件:

Class LibExample {

public:
    static LibExample* getInstance();

private:
    class Helper {
    public:
        Helper() {
            libExampleInstance = new LibExample();
        }
        ~Helper() {
            delete libExampleInstance;
        }

        LibExample* libExampleInstance;
     };

    static LibExample* m_instance;

    LibExample();
    virtual ~LibExample();
    LibExample (const LibExample& ) {};
    LibExample& operator=(const LibExample&) {
        return *(LibExample::getInstance());
    }
};
在.cpp文件中:

LibExample* LibExample::m_instance = NULL;

LibExample* LibExample::getInstance() {
    static Helper instance;
    if(m_instance == NULL) {
        m_instance = instance.libExampleInstance;
        int ret = m_instance->init();
        if(ret < 0) {
           m_instance = NULL;
        }
    }
    return m_instance;
}
LibExample*LibExample::m_instance=NULL;
LibExample*LibExample::getInstance(){
静态助手实例;
if(m_实例==NULL){
m_instance=instance.libExampleInstance;
int ret=m_instance->init();
如果(ret<0){
m_instance=NULL;
}
}
返回m_实例;
}
在那里,他们使用“助手”来实例化单例。为什么这是必要的

事实并非如此。这里可以使用
Helper
来允许
m_instance==NULL
测试,并在首次使用
getInstance
时调用
init
,但是
init
也可以在
LibExample
构造函数中运行。可能有一个模糊的原因,但我觉得这个设计过于复杂了

你可以:

Class LibExample {

public:
    static LibExample* getInstance();

private:
    LibExample();
    virtual ~LibExample();
    LibExample (const LibExample& ) {};
    LibExample& operator=(const LibExample&) {
        return *(LibExample::getInstance());
    }
};

LibExample* LibExample::getInstance() {
    static LibExample instance;
    static LibExample* p_instance = NULL;
    if(p_instance == NULL) {
        int ret = instance.init();
        if(ret >= 0) {
            p_instance = &instance;
        }
    }
    return p_instance;
}

编辑:

正如@SingerOfTheFall在评论中指出的:


我认为这样做是为了实现某种延迟初始化:如果
init()
第一次失败,则不需要重新构造单例本身,它将在下次调用实例时尝试重新初始化自身


仍然
Helper
是不必要的:我相应地修改了我的代码。

我想象:在每次执行失败的
init
时,都能够使实例
m_实例
为空,而不必释放/重新分配内存。我不明白的是,如果不涉及多态性,为什么他们会在堆上而不是堆栈上分配内存。@ChrisR.,
我不明白的是,为什么他们会在堆上而不是堆栈上分配内存
我不知道这种特殊情况,但在某些情况下(例如,当您使用嵌入式时),堆栈大小可能会受到很大限制,以至于足够大的对象实例根本无法容纳。我认为这样做是为了实现某种延迟初始化:如果
init()
第一次失败,则不需要重新构造singleton本身,下次调用实例时,它会尝试重新初始化自身。@如果你是对的,我在回答中集成了这一点。我认为新代码可能仍然存在一些问题,比如多线程将调用
init
,因此无法避免锁。@Danh是的,但是,如果我错了,请纠正我,
Helper
类不会改变这一点。应该使用互斥锁(?)是的,我认为互斥锁应该在
init
中使用,但我认为它违背了静态局部对象的目的。无论如何,我发现这个实现过于复杂,我认为一个
bool
值就足够了