单例模式

   在编写代码工程时,很多时候我们需要对象的唯一性,即整个工程或项目中只需要类的一个实例。可以通过设计模式的单例模式来实现。以下是我用c++实现的两种方式:

第二种较第一种代码逻辑稍简单些。

class Singlton
{
private:
<span style="white-space:pre">	</span>int m_nNum;
<span style="white-space:pre">	</span>static Singlton* m_pSinglton;
<span style="white-space:pre">	</span>Singlton(int num)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>m_nNum = num;
<span style="white-space:pre">		</span>std::cout<<"construct Singlton!"<<endl;
<span style="white-space:pre">	</span>}
public:
<span style="white-space:pre">	</span>static Singlton* getInstance()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>if (m_pSinglton == NULL)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>m_pSinglton = new Singlton(1);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>return m_pSinglton;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
};
Singlton* Singlton::m_pSinglton = new Singlton(1);
int main(int argc, char *argv[])
{
<span style="white-space:pre">	</span>QCoreApplication a(argc, argv);
<span style="white-space:pre">	</span>Singlton::getInstance();
<span style="white-space:pre">	</span>return a.exec();
}

这种方法是通过静态成员变量和静态成员函数来实现的。该代码有一点需要注意:

1、Singlton* Singlton::m_pSinglton = new Singlton(1);    静态成员变量能用私有构造函数来构造吗?私有的为什么有访问权限。

要理解这个问题首先要了解访问类的成员有两种方式:(1)通过this指针(2)通过作用域。处于作用域中的可以访问作用域中的所有成员。如:

class Test
{
private:
  int num;
public:
void Init();
};
//declare.cpp
include"declare.h"
void Test::Init()
{
  num=1;//num也是Test的private成员
}
类似于上面的代码,静态成员变量 Singlton::m_pSinglton 处于Singlton作用域中,所以能访问私有构造函数。

第二种方法使用了局部静态变量方式实现

class Singlton
{
private:
	Singlton()
	{
		std::cout<<"construct Singlton!"<<endl;
	}
public:
	static Singlton* getInstance()
	{
		static Singlton m_pSinglton;
		return &m_pSinglton;
	}
};

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);
	Singlton::getInstance();
	return a.exec();
}

由于局部静态变量的作用域是整个生命周期,所以可以利用这种方式创建单例,较第一种更为简单。

但是以上两种方式都不是线程安全的。如果有多个线程同时调用getInstance,可能会创建出多个实例,违背了单例模式。当然可以使用线程同步机制(如进行加锁解锁),但是这些机制速度慢开销大,可以考虑使用原子操作来弥补这一缺陷。后续会添加通过原子操作来实现多线程线下线程安全问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值