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
值就足够了