设计模式之单例模式

单例是使用静态变量使得程序中只有一个实体对象的抽象方法,是一种共享类全局对象的方法。优点是:确保一个类只创建一个实例;为对象分配和销毁提供控制;支持线程安全地访问对象的全局状态;避免污染全局命名空间

1 单例实现



上述中的单例通过静态成员变量和静态成员函数实现,静态成员函数getInstance()会对静态成员instance进行实例化,并通过此进行函数接口的调用。

上述实现中优点是通过全局函数getInstance()来访问全局静态成员变量,进而能使用其方法,但调用时“Singleton::getInstance().display()”代码长度过长,可以把display函数声明为静态方法,内部调用instance的私有方法_display减少代码的书写,即


这样做的好处是可以声明外部接口为共有的静态成员函数,其他具体实现接口都是私有的,避免了错误访问(且getInstance()方法也应该设置成私有,防止单例对象赋值和拷贝)。

2 单例使用

比较适合使用单例的情况有:日志类,配置类,共享资源类等。这些例子有以下特性:

Ø 如果我们不使用它,就不会创建实例。即getInstance()Lazy Initial的,单例只在第一次使用时进行初始化,如果不使用则不进行初始化。

Ø 它在运行时初始化,即单例也可以在其初始化时引用另一个单例。

Ø 单例可以继承(见代码链接)。

3 扩展

3.1 线程安全的单例

前面的getInstance()实现不是线程安全,因为单例的静态初始化存在竞态条件,如果恰好有两个线程同时调用该方法,那么示例可能被构造两次,或者在一个线程完成初始化示例前另外一个线程就调用了该实例。解决方法是在竞态条件的代码前后添加互斥锁实现线程安全。

static Mutex mutex

Singleton &Singleton::getInstance()

{

ScopedLock lock(&mutex); //在函数退出时释放互斥锁

static Singleton instance;

return instance;

}

上述解决方案的潜在问题是开销较大,因为每次调用时都要请求加锁。另外可用双重检查锁定模式(double check locking pattern

Singleton &Singleton::getInstance()

{

static Singleton *instance = NULL;

if(instance == NULL) //检查#1

{

Mutex mutex;

ScopedLock lock(&mutex);

 

if(instance == NULL) //检查#2

{

instance = new Singleton();

}

}

return *instance;

}

(补充:C++11保证一个局部静态变量的初始化只进行一次,哪怕是在多线程的情况下也是如此)

参考文献:

[1]http://www.oodesign.com/singleton-pattern.html

[2]C++ API设计》

[3]《游戏编程模式》


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值