面试题:C++设计一个单例类
众多设计模式中最简单的一个。
考察两个地方:1.如何实现单例;2.如何正确的释放这唯一的实例。
class singleton { public: static singleton* getInstance() { if (!ptr_singleton) { ptr_singleton = new singleton(); } return ptr_singleton; } private: singleton() {} ~singleton() {} class CAss//辅助类,它的唯一用途就是程序结束时,释放singleton的唯一实例 { public: ~CAss() { if (singleton::ptr_singleton) delete singleton::ptr_singleton; } }; static CAss Ass; static singleton* ptr_singleton; }; singleton* singleton::ptr_singleton = 0;//注意静态成员的声明和定义的区别 singleton::CAss singleton::Ass = singleton::CAss();
代码非常的简单,注意判断ptr_singleton为空的情况,别粗心这题就是送分。
嗯,唯一的技巧吧,就是利用了C++在结束时自动释放所有的静态成员。(额,你可能会迷惑,ptr_singleton也是静态成员呀?嗯,它是的,可它指向的对象就不是咯,堆上的对象需要手动释放)
2015.5.6 增加需求设计:能够在多线程下正确运行。
代码很巧妙,先看代码:
class singleton
{
public:
static singleton* getInstance()
{
static singleton instance;
return &instance;
}
private:
singleton()
{}
~singleton()
{}
class CAss
{
public:
CAss()
{
getInstance();//一定是在单线程的情况第一次调用getInstance
}
};
static CAss Ass;//C++标准规定了全局变量一定在main函数前初始化完成
};
singleton::CAss singleton::Ass;
很巧妙的实现方法,来自boost
修改了单例类的数据成员的存在方式:利用编译器最后自动回收静态成员的机制,帮助了我们自动析构singleton的实例。
修改了辅助类的作用,因为多线程可能会出现错误,一定是因为singleton的唯一实例没有初始化的情况。只要我们保证了在多线程的情况下,实例已经被初始化了,那问题就引刃而解了。因为:C++标准规定了全局变量一定在main函数前初始化完成。
以上
单例模式