单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。本文展示c++语言中单例模式的几种实现方式及细节处理。
第一种:使用静态成员实例。
#include <iostream>
using namespace std;
class singleton
{
public:
static singleton* GetInstance()
{
if ( m_instance == NULL )
{
cout<<"a new instance"<<endl;
m_instance = new singleton();
}
return m_instance;
}
void release()
{
if(this->m_instance!=NULL)
{
delete this->m_instance;
m_instance=NULL;//注意delete之后将指针设为null
cout<<"free the instance"<<endl;
}
}
private:
singleton(){}
static singleton * m_instance;
};
singleton* singleton::m_instance = NULL;
int main()
{
singleton* s=singleton::GetInstance();
singleton* t=s->GetInstance();
cout<<s<<endl<<t<<endl;
t->release();
return 0;
}
执行结果如下:
两个指针地址相同,说明是同一个指向singleton的指针。
为什么静态成员变量一定指针而不是singleton对象呢?因为直接返回对象是值传递,返回的是实例的副本。那为什么不返回一个引用呢?
#include <iostream>
using namespace std;
class singleton
{
public:
static singleton& getOnlyInstance()
{
return theOnlyInstance;
}
private:
singleton(){
cout<<"singleton build"<<endl;
}
static singleton theOnlyInstance;
};
singleton singleton::theOnlyInstance=*(new singleton());
int main()
{
cout<<&singleton::getOnlyInstance()<<endl;
cout<<&singleton::getOnlyInstance()<<endl;
singleton s=singleton::getOnlyInstance();
singleton q=singleton::getOnlyInstance();
cout<<&s<<endl<<&q<<endl;
return 0;
}
运行结果如下:
可以看到,返回的确实是同一个实例了,同时却出现了另一个问题:这个唯一的实例可以通过赋值来创建副本,这就打破了单例模式的初衷。不过我们可以通过将拷贝构造函数和赋值运算符重载函数写为private来避免客户的复制操作。不过比起指针,这种方式用起来还是有些不方便。
#include <iostream>
using namespace std;
class singleton
{
public:
static singleton& getOnlyInstance()
{
return theOnlyInstance;
}
private:
singleton(singleton &){}
singleton operator=(singleton&){};
singleton(){
cout<<"singleton build"<<endl;
}
static singleton theOnlyInstance;
};
singleton singleton::theOnlyInstance=*(new singleton());
int main()
{
cout<<&singleton::getOnlyInstance()<<endl;
cout<<&singleton::getOnlyInstance()<<endl;
//singleton s=singleton::getOnlyInstance();
//singleton q=singleton::getOnlyInstance();
//s=q;
//cout<<&s<<endl<<&q<<endl;
return 0;
}
第二种:使用静态局部实例。同样地需要避免赋值的发生。
#include <iostream>
using namespace std;
class singleton
{
public:
static singleton& getOnlyInstance()
{
static singleton theOnlyInstance;
return theOnlyInstance;
}
private:
singleton(singleton &){}
singleton operator=(singleton&){};
singleton(){
cout<<"singleton build"<<endl;
}
};
int main()
{
cout<<&singleton::getOnlyInstance()<<endl;
cout<<&singleton::getOnlyInstance()<<endl;
//singleton s=singleton::getOnlyInstance();
//singleton q=singleton::getOnlyInstance();
//s=q;
cout<<&s<<endl<<&q<<endl;
return 0;
}
或者使用返回指向局部实例的指针来实现:
#include <iostream>
using namespace std;
class singleton
{
public:
static singleton* getOnlyInstance()
{
static singleton theOnlyInstance;
return &theOnlyInstance;
}
private:
//singleton(singleton &){}
//singleton operator=(singleton&){};
singleton(){
cout<<"singleton build"<<endl;
}
};
int main()
{
cout<<singleton::getOnlyInstance()<<endl;
cout<<singleton::getOnlyInstance()<<endl;
singleton* s=singleton::getOnlyInstance();
singleton* q=singleton::getOnlyInstance();
//s=q;
cout<<s<<endl<<q<<endl;
return 0;
}