您的位置:首页 > 编程语言 > C语言/C++

c++设计模式:单件模式(Singleton Pattern)

2013-04-06 17:45 309 查看
定义:单件模式确保一个类只有一个实例,并提供一个全局访问点

实现一:



#include<iostream>
usingnamespacestd;

classCSingleton
{
public:
staticCSingleton*getInstance();
staticvoidcleanInstance();
intgetValue();
voidsetValue(intiValue);
private:
intm_iValue;
staticCSingleton*m_pSingleton;
CSingleton();
~CSingleton();
};

CSingleton*CSingleton::m_pSingleton=NULL;

CSingleton::CSingleton()
{
cout<<"Constructor"<<endl;
}

CSingleton::~CSingleton()
{
cout<<"Destructor"<<endl;
}

CSingleton*CSingleton::getInstance()
{
if(NULL==m_pSingleton)
{
m_pSingleton=newCSingleton();
}
returnm_pSingleton;
}

voidCSingleton::cleanInstance()
{
deletem_pSingleton;
}

intCSingleton::getValue()
{
returnm_iValue;
}

voidCSingleton::setValue(intiValue)
{
m_iValue=iValue;
}

intmain()
{
CSingleton*pSingleton1=CSingleton::getInstance();
CSingleton*pSingleton2=CSingleton::getInstance();
pSingleton1->setValue(123);
if(pSingleton1->getValue()==pSingleton2->getValue())
{
cout<<"Twoobjectsisthesameinstance"<<endl;
}
else
{
cout<<"Twoobjectsisn'tthesameinstance"<<endl;
}

CSingleton::cleanInstance();
return0;
}




相信大多数的同仁都喜欢使用上边这种单件模式的实现方法,如果在单线程的情况下,是没有问题的,但如果是多线程,那么就极有可能会返回两个不同的对象,在调用
CSingleton::getInstance的时候,两个线程如果都同时运行完if判断,而又还没有调用到构造函数的话,想象下后果吧。那该怎么办呢?看下边这个实现吧。

实现二:




#include<iostream>
usingnamespacestd;

classCSingleton
{
public:
staticCSingleton*getInstance();
staticvoidcleanInstance();
intgetValue();
voidsetValue(intiValue);
private:
intm_iValue;
staticCSingleton*m_pSingleton;
CSingleton();
~CSingleton();
};

//在进程运行开始就实例化该单件,又称“急切”创建实例
CSingleton*CSingleton::m_pSingleton=newCSingleton();

CSingleton::CSingleton()
{
cout<<"Constructor"<<endl;
}

CSingleton::~CSingleton()
{
cout<<"Destructor"<<endl;
}

CSingleton*CSingleton::getInstance()
{
returnm_pSingleton;
}

voidCSingleton::cleanInstance()
{
deletem_pSingleton;
}

intCSingleton::getValue()
{
returnm_iValue;
}

voidCSingleton::setValue(intiValue)
{
m_iValue=iValue;
}

intmain()
{
CSingleton*pSingleton1=CSingleton::getInstance();
CSingleton*pSingleton2=CSingleton::getInstance();
pSingleton1->setValue(123);
if(pSingleton1->getValue()==pSingleton2->getValue())
{
cout<<"Twoobjectsisthesameinstance"<<endl;
}
else
{
cout<<"Twoobjectsisn'tthesameinstance"<<endl;
}

CSingleton::cleanInstance();
return0;
}




哈哈,看清楚了吗?就是在进程运行的时候就对这个单件进行实例化,可是这样似乎又不能达到延迟实例化的目的啦。如果我们的对象对资源占用非常大,而我们的进行在整个过程中其实并没有用到这个单件,那岂不是白白浪费资源了嘛。还有更好的办法。

实现三:




#include<iostream>
usingnamespacestd;

classCSingleton
{
public:
staticCSingleton*getInstance();
intgetValue();
voidsetValue(intiValue);
private:
intm_iValue;
CSingleton();
~CSingleton();
};

CSingleton::CSingleton()
{
cout<<"Constructor"<<endl;
}

CSingleton::~CSingleton()
{
cout<<"Destructor"<<endl;
}

CSingleton*CSingleton::getInstance()
{
staticCSingletonsingle;
return&single;
}

intCSingleton::getValue()
{
returnm_iValue;
}

voidCSingleton::setValue(intiValue)
{
m_iValue=iValue;
}

intmain()
{
cout<<"Processbegin"<<endl;
CSingleton*pSingleton1=CSingleton::getInstance();
CSingleton*pSingleton2=CSingleton::getInstance();
pSingleton1->setValue(123);
if(pSingleton1->getValue()==pSingleton2->getValue())
{
cout<<"Twoobjectsisthesameinstance"<<endl;
}
else
{
cout<<"Twoobjectsisn'tthesameinstance"<<endl;
}
return0;
}




看下运行结果吧:


Processbegin

Constructor

Twoobjectsisthesameinstance

Destructor

是不是跟预想的一样呢?把单件声明为成员函数中的静态成员,这样既可以达到延迟实例化的目的,又能达到线程安全的目的,而且看结果的最后,是不是在程序退出的时候,还自动的调用了析构函数呢?这样我们就可以把资源的释放放到析构函数里边,等到程序退出的时候,进程会自动释放这些静态成员的。

参考图书:《HeadFirst设计模式》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: