这个想法是在程序结束时删除C++中的Singleton.我们在课堂上学到了这种实现方法:
class Singleton
{
private:
static Singleton* the_singleton;
protected:
Singleton()
{
static Keeper keeper(this);
/*CONSTRUCTION CODE*/
}
virtual ~Singleton()
{
/*DESTRUCTION CODE*/
}
public:
class Keeper
{
private:
Singleton* m_logger;
public:
Keeper(Singleton* logger):m_logger(logger){}
~Keeper()
{
delete m_logger;
}
};
friend class Singleton::Keeper;
static Singleton* GetInstance();
{
if (!the_singleton)
the_singleton = new Singleton();
return the_singleton;
}
};
Singleton* Singleton::the_singleton = NULL;
Run Code Online (Sandbox Code Playgroud)
我们的想法是,在第一次创建Singleton时,将在Singleton的C'tor中创建一个静态Keeper对象,一旦程序结束,Keeper将被销毁,反过来将破坏它指向的Singleton实例至.
现在,这个方法对我来说似乎相当麻烦,所以我建议抛弃守护者类并使Singleton的实例成为getInstance方法的静态对象:
<!-- language: c++ -->
class Singleton
{
protected:
Singleton()
{
/*CONSTRUCTION CODE*/
}
~Singleton()
{
/*DESTRUCTION CODE*/
}
public:
static Singleton &getInstance()
{
static Singleton instance;
return instance;
}
/*OBJECT FUNCTIONALITY*/
};
Run Code Online (Sandbox Code Playgroud)
这样,Singleton是在第一次调用getInstance方法时构造的,并在程序结束后销毁.不需要那个守门员课程.
我测试了它并且工作得很好 - 在正确的地方创建并销毁了Singleton.但是,我的TA说这种模式是错误的,尽管他不记得究竟是什么问题.所以我希望以前有人遇到过这个实现,并告诉我它有什么问题.
这是错的,但你的修改没有引入问题 - 他们一直都在那里.
现在没有执行单身人士财产.构造函数需要是私有的,而不是受保护的,以确保不创建其他实例.
除此之外,原始代码在多线程场景中完全无法使用. 你的工作将从C++ 0x开始.
如果TA的keeper对象已将全局指针重置为NULL,则他的实现将能够(在单线程环境中)在程序清理期间根据需要重新创建单例.在C++中读取单例模式.但这仍然是单例的一个新实例,这几乎与在调用析构函数后使用单例一样出乎意料.
但是,他忽略了这一点,因此在守门员删除单身人士之后,他会很乐意在程序关闭期间使用无效指针.在你的内容中,即使对象的生命周期已经结束,至少内存区域仍然有效.
您当然会被标记为使用改进版本,这只是表明该类的目的不是教你C++,而是TA对C++的误解.
完全没有问题.对于这个应用程序,"守护者"的东西是坚果,恕我直言.
在某些情况下可能需要保证.例如,如果Singleton必须采用构造函数参数,则静态分配它可能是不可能的.或者,如果其构造函数可能失败,则更简单的方法将不允许您恢复或重试.所以在某些情况下,可能需要做一些更复杂的事情.但在许多情况下,这是不必要的.