题目二:实现单例模式

////////////////////////////////////////////////////////////////////////////////////////////////////////

// 4.单例模式测试

extern CMutex g_stMutex;    // 这个在ThreadTest.cpp中定义了,这个声明一下!!!!

class CSingletonTest
{
public:
    CSingletonTest() :m_iCount(0){}
    ~CSingletonTest(){}
    void AddCount() { m_iCount++; }
    void SubCount() { m_iCount--; }
    int GetCount() { return m_iCount; }

private:
    int m_iCount;
};

class CSingleton_1
{
protected:
    // 禁止外部调用这几个函数
    CSingleton_1(){}
    ~CSingleton_1(){}
    CSingleton_1(const CSingleton_1&);
    CSingleton_1& operator=(const CSingleton_1&);

};

///////////////////////////////////////////////////////
// 懒汉模式
//类加载进来,没有对象,只有调用了getInstance方法时,才会创建对象。
//延迟加载形式。 并发过程中存在安全隐患。

template <typename TYPE>
class CSingleton_2 : public CSingleton_1
{
public:
    static TYPE* GetInstance()
    {
        if (NULL == m_pSingleton)
        {
            cout << "Try Lock --------------->" << endl;
            m_pSingleton = new CSingleton_2<TYPE>();
        }

        return &m_pSingleton->m_stInstance;
    }
private:
    static CSingleton_2<TYPE>* m_pSingleton;
    TYPE m_stInstance;

private:
    // 自动释放内存(不需要定义也可以,程序结束是系统会自动回收)
    class CGarbo
    {
    public:
        ~CGarbo()
        {
            if (m_pSingleton)
            {
                delete m_pSingleton;
                m_pSingleton = NULL;
            }
        }
    };

    static CGarbo garbo;
};

template <typename TYPE>
CSingleton_2<TYPE>* CSingleton_2<TYPE>::m_pSingleton;

typedef CSingleton_2<CSingletonTest> SingletonTesHEAP_TYPE;

////////////////////////////////////////////////////////////
// 加锁的懒汉实现
template <typename TYPE>
class CSingleton_3 : public CSingleton_1
{
public:
    static TYPE* GetInstance()
    {
        if (NULL == m_pSingleton)
        {
            cout << "Try Lock --------------->" << endl;
            CLock lock(g_stMutex);
            if (NULL == m_pSingleton)
            {
                m_pSingleton = new CSingleton_3<TYPE>();
            }
        }
        return &m_pSingleton->m_stInstance;
    }
private:
    static CSingleton_3<TYPE>* m_pSingleton;
    TYPE m_stInstance;
};

template <typename TYPE>
CSingleton_3<TYPE>* CSingleton_3<TYPE>::m_pSingleton;

typedef CSingleton_3<CSingletonTest> SingletonTest3;

////////////////////////////////////////////////////////////////
// 饿汉模式
template <typename TYPE>
class CSingleton_4 : public CSingleton_1
{
public:
    static TYPE* GetInstance()
    {
        //return &(const_cast<CSingleton2<TYPE>*>(m_pSingleton)->m_stInstance);
        return &(const_cast<CSingleton_4<TYPE>*>(m_pSingleton)->m_stInstance);
    }
private:
    const static CSingleton_4<TYPE>* m_pSingleton;
    TYPE m_stInstance;
};

template <typename TYPE>
const CSingleton_4<TYPE>* CSingleton_4<TYPE>::m_pSingleton = new CSingleton_4<TYPE>;
typedef CSingleton_4<CSingletonTest> SingletonTest4;

////////////////////////////////////////////////////////////////////////
// 多线程测试函数
template <typename TYPE>
class CSingletonThreadTest : public CThread
{
public:
    CSingletonThreadTest(const string& str) :m_szThreadName(str) {}
    ~CSingletonThreadTest(){}

    virtual void Run()
    {
        for (int i = 0; i < 5000; i++)
        {
            //CLock Lock(g_stMutex);
            TYPE::GetInstance()->AddCount();
            //cout << m_szThreadName << ": " << TYPE::GetInstance()->GetCount() << endl;
        }
    }

private:
    string m_szThreadName;
};

void CSingleton_2TestFunc()
{
    cout << "\n\n --------------- CSingleton_2TestFunc Start -------------->" << endl;
    double dStart = clock();

    // 1.单线程测试
    CSingletonTest* pTest = SingletonTesHEAP_TYPE::GetInstance();
    pTest->AddCount();
    cout << "pTest Count = " << pTest->GetCount() << endl;

    // pTest 和 pTesHEAP_TYPE指向同一个对象
    CSingletonTest* pTesHEAP_TYPE = SingletonTesHEAP_TYPE::GetInstance();
    pTesHEAP_TYPE->AddCount();
    cout << "pTesHEAP_TYPE Count = " << pTesHEAP_TYPE->GetCount() << endl;

    // 2.多线程下测试 测试5000数据,加锁情况下5000, 不加锁不一定为5000
    CSingletonThreadTest<SingletonTesHEAP_TYPE> Test1("Test1");
    Test1.Start();
    CSingletonThreadTest<SingletonTesHEAP_TYPE> TesHEAP_TYPE("TesHEAP_TYPE");
    TesHEAP_TYPE.Start();
    CSingletonThreadTest<SingletonTesHEAP_TYPE> Test3("Test3");
    Test3.Start();
    CSingletonThreadTest<SingletonTesHEAP_TYPE> Test4("Test4");
    Test4.Start();
    CSingletonThreadTest<SingletonTesHEAP_TYPE> Test5("Test5");
    Test5.Start();

    CT_SLEEP(1);

    cout << "CSingleton_2TestFunc : " << SingletonTesHEAP_TYPE::GetInstance()->GetCount() << endl;
    cout << "花费时间: " << (clock() - dStart) / CONST_1000 << endl;

    cout << "\n\n --------------- CSingleton_2TestFunc End -------------->" << endl;

}

template <typename TYPE>
void SingletonTestFunc()
{
    //double dStart = clock();
    // 1.单线程测试
    TYPE::GetInstance()->AddCount();
    TYPE::GetInstance()->AddCount();
    cout << typeid(TYPE::GetInstance()).name() << ": Count = " << TYPE::GetInstance()->GetCount() << endl;

    CSingletonThreadTest<TYPE> Test1("Test1");
    Test1.Start();
    CSingletonThreadTest<TYPE> TesHEAP_TYPE("TesHEAP_TYPE");
    TesHEAP_TYPE.Start();
    CSingletonThreadTest<TYPE> Test3("Test3");
    Test3.Start();
    CSingletonThreadTest<TYPE> Test4("Test4");
    Test4.Start();
    CSingletonThreadTest<TYPE> Test5("Test5");
    Test5.Start();

    CT_SLEEP(10);

    cout << "SingletonTestFunc : " << TYPE::GetInstance()->GetCount() << endl;
    //cout << "花费时间: " << (clock() - dStart) / CONST_1000 << endl;
}

void SingletonPatternTestFunc()
{
    cout << "\n\n --------------- SingletonPatternTestFunc Start -------------->" << endl;

    //CSingleton_2TestFunc();

    SingletonTestFunc<SingletonTesHEAP_TYPE>();

    cout << "===================================================>>>" << endl;

    SingletonTestFunc<SingletonTest3>();

    cout << "===================================================>>>" << endl;
    SingletonTestFunc<SingletonTest4>();

    cout << "\n\n --------------- SingletonPatternTestFunc End -------------->" << endl;

}

原文地址:https://www.cnblogs.com/yzdai/p/11258589.html

时间: 2024-11-09 00:44:12

题目二:实现单例模式的相关文章

Java设计模式(二)-单例模式

单例模式建议保证某个对象仅仅只有一个实例,当只有一个对象来协调整个系统的操作时,在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例,总之,选择单例模式就是为了避免不一致状态,避免政出多头. 下面是单例模式的类图:包括的private和static修饰的实例instance.一个private的构造函数.一个static的getInstance函数 单例模式主要有三种:懒汉式单例.饿汉式单例.登记式单例三种 1.饿汉式单例:在类的初始化时候,自行创建了实例 c

java设计模式(二)单例模式 建造者模式

(三)单例模式 单例模式应该是最常见的设计模式,作用是保证在JVM中,该对象只有一个实例存在. 优点:1.减少某些创建比较频繁的或者比较大型的对象的系统开销. 2.省去了new操作符,降低系统内存使用频率,减轻GC压力. 3.保证核心代码的唯一性,比如交易引擎. 单例模式看似是最简单的设计模式. public class Singleton { //私有构造方法,防止实例化 private Singleton(){ } //创建类的实例的时候加载 private static Factory f

ninject学习笔记二:单例模式singleton pattern

今天准备学习singleton pattern,顾单词思含义,就是一个实例的意思.单例的实现思路是:私有化构造函数,提供公有方法获取类的实例.下面定义一个音乐播放器类MusicPlayer,观察单例的实现方法 class MusicPlayer { private static readonly MusicPlayer player = new MusicPlayer(); private MusicPlayer() { } public static MusicPlayer GetInstan

PHP设计模式二:单例模式

一.什么是单例模式 作为对象的创建模式,单例模式确保某一个类只有一个实例,并且对外提供这个全局实例的访问入口.它不会 创建实例副本,而是会向单例类内部存储的实例返回一个引用. 二.PHP单例模式三要素 1. 需要一个保存类的唯一实例的静态成员变量. 2. 构造函数和克隆函数必须声明为私有的,防止外部程序创建或复制实例副本. 3. 必须提供一个访问这个实例的公共静态方法,从而返回唯一实例的一个引用. 三.为什么使用单例模式 使用单例模式的好处很大,以数据库操作为例.若不采用单例模式,当程序中出现大

Unity3d与设计模式(二)单例模式

为什么要使用单例模式 在我们的整个游戏生命周期当中,有很多对象从始至终有且只有一个.这个唯一的实例只需要生成一次,并且直到游戏结束才需要销毁. 单例模式一般应用于管理器类,或者是一些需要持久化存在的对象. Unity3d中单例模式的实现方式 (一)c#当中实现单例模式的方法 因为单例本身的写法不是重点,所以这里就略过,直接上代码. 以下代码来自于MSDN. public sealed class Singleton { private static volatile Singleton inst

设计模式(二)单例模式Singleton(创建型)

几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的.您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销.再如大家最经常用的IM,如QQ,在同一台电脑,一个帐号只能有唯一的登录. 1. 问题 怎样确保一个特殊类的实例是独一无二的(它是这个类的唯一实例),并且这个实例易于被访问呢? 2. 解决方案 1)全局变量:一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象.因为你的任何代码都能修改全局变量,这将不可避免的引起

【NopCommerce源码架构学习-二】单例模式实现代码分析

单例模式是是常用经典十几种设计模式中最简单的..NET中单例模式的实现也有很多种方式.下面我来介绍一下NopCommerce中单例模式实现. 我之前的文章就分析了一下nop中EngineContext的实现.EngineContext是把一个Web请求用Nop的EngineContext引擎上下文封装.里面提供了一个IEngine的单例对象的访问方式. 下面就是EngineContext的源码: 一.EngineContext 1 using System.Configuration; 2 3

《剑指Offer》题目——二维数组中的查找

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 题目分析: 暴力破解时间复杂度太高,本题有两种思路:1. 将每行看成一个有序数组,用二分查找2. 从左下角开始查找,若大于该值,右移:若小于该值,上移,直到找到为止 public class ArraySearch { public static boolean Find(int target, int [][] ar

设计模式(二)单例模式(转)

原文地址:http://www.jellythink.com/archives/82 问题描述 现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能:在实际开发过程中,会专门有一个日志模块,负责写日志,由于在系统的任何地方,我们都有可能要调用日志模块中的函数,进行写日志.那么,如何构造一个日志模块的实例呢?难道,每次new一个日志模块实例,写完日志,再delete,不要告诉我你是这么干的.在C++中,可以构造一个日志模块的全局变量,那么在任何地方就都可以用了,是的,不错.