今天实现一个单例的时候,想到多线程getInstance()时可能会有问题,就查了一下单例的几种实现方式。
有一种被称为“饿汉式”的实现:
1 class manager 2 { 3 private: 4 manager(){printf("called.");} 5 static manager* m_pInstance; 6 7 public: 8 manager* GetInstance() 9 { 10 return m_pInstance; 11 } 12 } 13 14 manager* manager::m_pInstance = new manager;
特点是:在静态区域创建实例,可以保证调用GetInstance()时永远返回同一个有效的指针,这样完美解决多线程的问题。
我的疑惑在最后一行:
manager* manager::m_pInstance = new manager;
既然 manager的构造函数已经是private了,为什么还能这样new一个对象呢?按理说,无法调用private构造函数,就无法创建对象啊。。。
我在测试时,程序打印了字符串“called.”,说明private构造函数确实被调用了。
为了验证不是代码的问题,我写了如下测试代码:
int main() { manager _m; }
程序编译失败,无法调用private的构造函数。
我猜想:
静态全局变量是存放在Data segment区域,而临时对象是存放在stack/heap区域,这两个地方有不同?
-------------------------------------------------------
ps:上面的实现有个小问题,按照程序的规则“调用new,则必然要delete”,该全局对象指针该由谁来delete呢?不太好处理。
最后使用了另外一种单例:
class manager { private: manager(){} public: manager* GetInstance() { static manager instance; return &instance; } }