当前位置: 首页 >> 程序设计 >> 学习设计模式之Singleton源码
 

学习设计模式之Singleton源码

作者:kubobo      来源:kubobo.cublog.cn     发表时间:2006-11-06     浏览次数:      字号:    

// Singleton.cpp : 定义控制台应用程序的入口点。

//

/************************************************************************/
/* 意图:
/* 保证一个类只有一个实例,并提供一个访问它的全局访问点
/*
/* 适用性:
/* 1. 同上
/* 2. 这个实例应该是通过子类化可扩展的,并且用户无需更改基类代码
/*
/* 效果:
/* 1. 对惟一实例的受控访问
/* 2. 缩小名空间。这是对全局变量的一种替代策略。
/* 3. 可继承,可生成多个实例(不同类型)
/* 4. 比类操作更灵活,相对类的静态函数,独体类对象的函数还可以体现多态性
/*
/* Author: kubobo
/* Date: 2006-11-4
/************************************************************************/

#include "stdafx.h"
#include <iostream>

//模拟多线程情况的加锁操作

#define MUTEX_LOCK()
#define MUTEX_UNLOCK()

using namespace std;


/************************************************************************/
/* Declaration */
/************************************************************************/
template<typename T>
class Singleton
{
public:
    //本来需要protected的访问权限的,作用有两个:

    //1. 子类继承的需要

    //2. 防止用户自行定义对象,保证独体类的惟一性

    //然而有了下面的virtual ~Singleton() = 0 {}

    //Singleton()完全解放了,呵呵~ 见下方。

    Singleton() {}

    //让Singleton成为抽象类,防止实例化一个无意义的基类对象(什么都没做),

    //使得只有通过继承方式实现独体类对象。有了这个限制,Singleton的构造函数

    //可以不用写了,或者标示为public还是private都无所谓了。

    virtual ~Singleton() = 0 {}

public:
    static T *Instance();
    static void Destroy();

private:
    //使用volatile,防止编译器优化,保持变量的原子性操作

    volatile static T *m_pSingleton;
};


class MySingleton : public Singleton<MySingleton>
{
//使父类成为友元类,否则不能在外部new出子类对象。

//当然,如果下面的构造函数为public,此处的friend则多余了,

//但是同时也给了用户自行创建对象的权利,不明智,嗯。

friend class Singleton<MySingleton>;

//防止用户自行定义对象,保证独体类的惟一性

private:
    MySingleton() {}

    //本来不用写析构函数也可以,但是想想如果main中出现

    //delete MySingleton::Instance();

    //可怎么办?还是婆婆妈妈一点吧~!

    virtual ~MySingleton() {}

public:
    void PrintOut();
};

/************************************************************************/
/* Implementation */
/************************************************************************/
template<typename T>
volatile T *Singleton<T>::m_pSingleton = NULL;


template<typename T>
T *Singleton<T>::Instance()
{
    //此处需要两个if,其实还是很有道理的^_^

    if (NULL == m_pSingleton)
    {
        MUTEX_LOCK();//互斥锁。要么进去,要么阻塞

        if (NULL == m_pSingleton)
        {
            m_pSingleton = new T();
        }
    }
    MUTEX_UNLOCK();//解锁,让阻塞的能进去


    return (T *)m_pSingleton;//不强制转换的话,VC8编译通不过。也许太严格了,唉~

}


template<typename T>
void Singleton<T>::Destroy()
{
    //一般由程序保证最后只调用销毁函数一次,不必加锁了

    if (m_pSingleton)
    {
        delete m_pSingleton;
        m_pSingleton = NULL;
    }
}


void MySingleton::PrintOut()
{
    cout << "MySingleton::PrintOut()" << endl;
}


/************************************************************************/
/* main */
/************************************************************************/
int _tmain(int argc, _TCHAR* argv[])//VC8的开发环境,请自行修改。PS:VC8真是好东东~

{
    MySingleton::Instance()->PrintOut();
    MySingleton::Destroy();

    return 0;
}


//后记:

//感觉自己写的这个Singleton比较繁琐,因为考虑了很多东西,正因为此,它也不是一次就写成的。

//实际上,我们用的最多的还是简单的方式,即以非继承的形式来使用Singleton模式。

//虽然“四人帮”一直强调继承的方式来使用,

//但至少在目前,我见到的一些真实系统中也都是使用简单的非继承方式。当然,

//使用了一些优化的办法来缩减工作量,比如用宏。嗯,不多说了,大家自己动手实践一下,

//只要符合意图中的两点要求就是Singleton,有好的创意请跟我交流哦~ ^_^

 

责任编辑 webmaster

 
 
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •