请教大家一个关于Singleton的问题
请看一段代码程序代码:
#include "stdafx.h" #include <stdio.h> #include <windows.h> class Singleton { protected: Singleton() {} private: Singleton(const Singleton&) {} Singleton& operator=(const Singleton&) { return *this; } ~Singleton() {} public: inline static Singleton *getInstance() { return m_pInstance; } private: static Singleton *m_pInstance; }; Singleton *Singleton::m_pInstance = new Singleton; class CriSec : public Singleton { protected: CriSec() {} public: void init() { InitializeCriticalSection(&m_objCriSec); } void lock() { EnterCriticalSection(&m_objCriSec); } void unlock() { LeaveCriticalSection(&m_objCriSec); } void release() { DeleteCriticalSection(&m_objCriSec); } private: CRITICAL_SECTION m_objCriSec; }; class Foo : public Singleton { protected: Foo() {} public: void foo() { printf("Hello,world!\n"); } }; int main(int argc, char* argv[]) { Foo *pObj1 = (Foo *)Foo::getInstance(); CriSec *pObj2 = (CriSec *)CriSec::getInstance(); pObj2->init(); pObj2->lock(); pObj1->foo(); pObj2->unlock(); pObj2->release(); return 0; }
这段代码主要实现了三个类,第一个为Singleton(单态,也就是说所有继承Singleton类的派生类只允许拥有唯一的一个实例),两外CriSec和Foo类都是继承Singleton的单态类,CriSec主要实现了临界区变量使用的封装,Foo类只是用来测试的。
问题是:
1、
对于Singleton中的静态成员初始化时直接new Singleton后通过getInstance()将m_pInstance返回给客户,这里存在一个问题,举个例子:
有类A,类B,其中类B继承类A,则
A *p = new B;
B *p1 = (B *)p; // 安全
而
A *p = new A;
B *p1 = (B *)p; // 不安全,B没有实例化,只能使用A提供的方法
那么这里问题来了,m_pInstance紧紧使之实例化为Singleton,而并没有实例化为Foo或CriSec类,为能安全的是用这两个类所提供的方法,从watch窗口可以看到,无论是Foo::getInstance()还是CriSec::getInstance()返回的都是同一个指针,却能安全使用这两个没有实例化的类感到很疑惑;若对于2个从Singleton派生的类能够正常工作,那么对于大于2个从Singleton派生的类,是否会造成不可预料的情况?
2、
其中静态成员m_pInstance一旦初始化后,即new了个指针出来,就没有办法删除了,原因之一是m_pInstance是个私有成员,第二个就是Singleton将析构私有化了,然而,通过实验,把m_pInstance和~Singleton()都置为public可以顺利通过编译,在程序最后加上delete m_pInstance;却发生断言,难道m_pInstance已经销毁类(不可能吧),还是static变量系统会自动清理?
程序能正常运行,希望大家给予帮助,谢谢。