Chinaunix首页 | 论坛 | 博客
  • 博客访问: 147202
  • 博文数量: 27
  • 博客积分: 2011
  • 博客等级: 大尉
  • 技术积分: 332
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-02 16:13
文章分类

全部博文(27)

文章存档

2009年(18)

2008年(9)

我的朋友

分类: C/C++

2008-08-20 16:37:53

Singleton.h

/*
 * 确保一个类只有一个实例,并提供一个全局访问点
 *
 * 应用 日志模块等
 *
 * 优于全局变量的地方
 * 1: 不污染全局名字空间
 * 2: 保证一个类只有一个实例,定义一个全局变量也可以定义一个局部
 */


class Singleton
{
public:
    static Singleton* instance(); // 只能通过这个函数来访问这个类的唯一实例

    
    void fun(); // 用来演示的方法, 可以是写log等其他实际需要的函数

    
protected:
    Singleton(); // 构造函数是protected的,不能用Singleton来定义对象,保证只能通过instance函数得到一个Singleton对象保证了一个类一个实例


private:
    static Singleton *_instance;
};

Singleton.cpp

#include "Singleton.h"
#include <iostream>
using namespace std;

Singleton* Singleton::_instance = NULL;

Singleton* Singleton::instance()
{
    if(_instance == NULL)
        _instance = new Singleton; // 只在第一次执行

    
    return _instance;
}

Singleton::Singleton()
{
}

void Singleton::fun()
{
    cout<<"Hello singleton"<<endl;
}

main.cpp

#include "Singleton.h"

/*
 * 下面这一句不能用,否则报错,因为类的构造函数是protected的
 * "main.cpp", line 8: Error: Singleton::Singleton() is not accessible from file level.
 * 这就保证了一个类只有一个实例
 */

// Singleton noway;


int main()
{
    Singleton::instance()->fun(); // 这里是使用Singleton的一个例子,在其他的类中都只要包含.h文件然后这么调用就可以了

    return 0;
}

 

上面的可以用于单线程,如果多线程,有可能多个线程同时看到指针为NULL,于是new新的对象,可能创建了多个对象,需要用到Double-Checked Locking避免这个问题。
 
加锁是针对instance函数
Singleton* Singleton::instance()
{
    // A
    if(_instance == NULL)
        // B
        _instance = new Singleton; // 只在第一次执行
    
    return _instance;
}
如果在A点上锁,可行;但是每次调用都上锁,效率低。
如果在B点上锁,不可行;不能保证只有一个实例。
 
Double-Checked Locking方法
Singleton* Singleton::instance()
{
    if(_instance == NULL)
    {
        // 在这加锁
        if(_instance == NULL) // 第二次检查
            _instance = new Singleton; // 只在第一次执行
    }
    return _instance;
}
由于加锁部分只执行一次或几次,之后不再执行,不影响效率。

总结
确保一个类只有一个实例,并且提供一个全局访问点。
一个静态类对象指针。
一个instance函数,第一次调用时new对象,并返回;不是第一次则直接返回已经创建的对象。
定义构造函数为protected或private,防止直接定义对象(只能用instance函数得到)。
多线程要结合Double-Checked Locking使用。
 
阅读(868) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~