-----Edit by ZhuSenlin HDU
方法一:利用私有静态成员变量static Singleton m_Instance实现
1) 因为只有一个实例,所以我们不能把构造函数借口暴露给用户(否则用户可以创建很多个)。所以采用一个静态成员函数static Singleton* GetInstance();来获取实例。
2) 因为只有一个实例,我们不想让用户随便删除,所以我们需要把析构函数设为私有。(其实直接delete也会出错,因为实例是在栈上分配的),为了使用户能方便的查找代码的疏漏,我们将析构函数设为私有,这样如果用户调用delete,会在编译期间报错,直接将其扼杀在摇篮里。
#include <iostream>
using namespace std;
//单例类
class Singleton
{
private:
static Singleton m_Instance;
int* ptest;
Singleton();
~Singleton();
public:
static Singleton* GetInstance();
void test();
};
Singleton Singleton::m_Instance;
Singleton::Singleton()
{
ptest = new int[10];
}
Singleton::~Singleton()
{
delete [] ptest;
ptest = NULL;
}
Singleton* Singleton::GetInstance()
{
return &m_Instance;
}
void Singleton::test()
{
cout << this << endl;
}
//测试代码
int main()
{
Singleton* pSingleton1 = Singleton::GetInstance();
pSingleton1->test();
Singleton* pSingleton2 = Singleton::GetInstance();
pSingleton2->test();
return 0;
}
方法二:利用单例抓取器来获取单例,每创建一个某个单例的抓取器,这个单例的引用计数加1,销毁一个某个单例的抓取器,该单例的引用计数就减1。当引用计数变为0时则销毁这个单例。如果再次创建该单例的抓取器,这个单例也有被重新实例化。
#include <iostream>
using namespace std;
//单例类
class Singleton
{
friend class SingletonGrabber;
private:
Singleton(){};
~Singleton(){};
public:
void test()
{
cout << this << endl;
}
};
//单例抓取器类
class SingletonGrabber
{
private:
static Singleton* m_pInstance;
static unsigned int m_nReference;
public:
SingletonGrabber();
~SingletonGrabber();
Singleton* GetInstance();
};
Singleton* SingletonGrabber::m_pInstance = NULL;
unsigned int SingletonGrabber::m_nReference = 0;
SingletonGrabber::SingletonGrabber()
{
if(m_pInstance == NULL)
m_pInstance = new Singleton();
m_nReference++;
}
SingletonGrabber::~SingletonGrabber()
{
m_nReference--;
if(m_nReference == 0)
{
delete m_pInstance;
m_pInstance = NULL;
}
}
Singleton* SingletonGrabber::GetInstance()
{
return m_pInstance;
}
//测试代码
int main()
{
SingletonGrabber grab;
Singleton* pSingleton1 = grab.GetInstance();
pSingleton1->test();
Singleton* pSingleton2 = grab.GetInstance();
pSingleton2->test();
return 0;
}
当然,这个抓取器可以应用到任何一个单例中,所以我们可以将其模板化。
#include <iostream>
using namespace std;
//单例类
class Singleton
{
template <class T>
friend class SingletonGrabber;
private:
Singleton(){};
~Singleton(){};
public:
void Test()
{
cout << this << endl;
}
};
//抓取器模板类
template <class T>
class SingletonGrabber
{
private:
static T* m_pInstance;
static unsigned int m_nRefernce;
public:
SingletonGrabber();
~SingletonGrabber();
T* GetInstance();
};
template <class T>
T* SingletonGrabber<T>::m_pInstance = NULL;
template <class T>
unsigned int SingletonGrabber<T>::m_nRefernce = 0;
template <class T>T* SingletonGrabber<T>::GetInstance(){return m_pInstance;}
template <class T>
SingletonGrabber<T>::SingletonGrabber()
{
if(m_pInstance == NULL)
m_pInstance = new T();
m_nRefernce++;
}
template <class T>
SingletonGrabber<T>::~SingletonGrabber()
{
m_nRefernce--;
if(m_nRefernce == 0)
{
delete m_pInstance;
m_pInstance = NULL;
}
}
//测试代码
int main()
{
SingletonGrabber<Singleton> grab;
Singleton* pSingleton1 = grab.GetInstance();
pSingleton1->Test();
Singleton* pSingleton2 = grab.GetInstance();
pSingleton2->Test();
return 0;
}
以上代码均经过测试,无内存泄露问题。