结合栈空间巧用单件

来源:互联网 发布:linux opengl 安装 编辑:程序博客网 时间:2024/06/08 18:02
    常说编程是个体力活,我也很认同;如果在编程的过程中学习使用设计模式,你会觉得那是一件有趣且轻松的玩意,如果再与朋友分享,那更可乐!
    这里介绍设计模式里的一个小兄弟:单件,相对于众多其它的模式这个最简洁不过,我阅读设计模式头一个感到亲切的便是这位小兄弟。自打看到它的第一刻便有一种相见恨晚的感叹,想想以前作配置总是extern全局变量,觉得好小家子气。
    OK,欢迎单件兄弟出场:

头文件:
class CSmartSt
{
public:
    void doSomething(int test);
   
    static CSmartSt *Instance();
    static void SafeReleasse();

protected:
    //mute construct function
    CSmartSt(void);
    CSmartSt(const CSmartSt &st){}
    CSmartSt & operator = (const CSmartSt & st){}
    ~CSmartSt(void);

private:
    //the only instance of smartst
    static CSmartSt *_instance;
    //reference count
    static long m_reference;
};


源文件:

CSmartSt *CSmartSt::_instance = NULL;
long CSmartSt::m_reference = 0;

CSmartSt::CSmartSt()
{
    printf("construct smart singleton/n");
}

CSmartSt::~CSmartSt()
{
    printf("destroy smart singleton/n/n");
}

void CSmartSt::doSomething(int test)
{
    printf("instance at (%8x) do something: %d!/n", _instance, test);
}

CSmartSt *CSmartSt::Instance()
{
    if (!_instance)
    {
        _instance = new CSmartSt;
    }
    //add reference cout by one
    InterlockedIncrement(&m_reference);
    return _instance;
}

void CSmartSt::SafeReleasse()
{
    //subtract reference cout by one
    InterlockedDecrement(&m_reference);
    if (m_reference <= 0)
    {
        delete _instance;
    }
}


这个结构想必大家都了解吧,它只能实例化一次,即所谓单件,另外安插了引用计数,只有当所有模块不再引用它时才被释放。不过要求每次使用它要先instance,使用完还要记住saferelease它,如果这样子将就着用也还可以,起码是个货真价实,童叟无欺的单件。

能不能再好呢,先看看下面的代码吧:
class CSmartSt;
class CSafeSingleton
{
public:
    CSafeSingleton();
    ~CSafeSingleton();

    CSmartSt *Inst();

private:
    CSmartSt *m_Inst;
};

CSafeSingleton::CSafeSingleton()
{
    m_Inst = CSmartSt::Instance();
}

CSafeSingleton::~CSafeSingleton()
{
    CSmartSt::SafeReleasse();
}

CSmartSt* CSafeSingleton::Inst()
{
    return m_Inst;
}

void Use1()
{
    CSafeSingleton sc;
    sc.Inst()->doSomething(1);
}

void Use2()
{
    CSafeSingleton sc;
    sc.Inst()->doSomething(2);
}

int _tmain(int argc, _TCHAR* argv[])
{
    //asset a instance, it is alive all along the programe life.
    CSafeSingleton globalst;
    globalst.Inst()->doSomething(0);

    Use1();
   
    Use2();

    getchar();
    return 0;
}



请注意上面这个Use函数,只要给点阳光(sc),它就能够灿烂(doSomething)。是不是更方便了。没错,就是巧用栈作到了自动saferelease。


上面有一个蛮土气的地方,需要在main函数里产生一个globalst的实例,其它Use函数才能不致于要新造单件实例而继续使用globalst.
能不能作得更好,不妨试试:

////////////////////////////////////////////////header file////////////
#pragma once

class CSmartSt;
class CSafeSingleton
{
public:
    CSafeSingleton();
    ~CSafeSingleton();

    CSmartSt *Inst();


private:
    CSmartSt *m_Inst;

};

class CSmartSt
{
public:
    void doSomething(int test);
   
    static CSmartSt *Instance();
    static void SafeReleasse();

protected:
    //mute construct function
    CSmartSt(void);
    CSmartSt(const CSmartSt &st){}
    CSmartSt & operator = (const CSmartSt & st){}
    ~CSmartSt(void);

private:
    //the only instance of smartst
    static CSmartSt *_instance;


public:
    //reference count
    static long m_reference;


    class CDestroy
    {
    public:
        CDestroy()
        {
            CSmartSt::Instance();
            printf("construct CDestroy reference is %d/n", CSmartSt::m_reference);
        }
        ~CDestroy()
        {
            CSmartSt::SafeReleasse();
            printf("destroy CDestroy reference is %d/n", CSmartSt::m_reference);
        }
    };
};


////////////////////////////////////////////////source file ///////////////////////////////////
#include "./smartst.h"
#include "windows.h"

CSmartSt *CSmartSt::_instance = NULL;
long CSmartSt::m_reference = 0;

CSmartSt::CSmartSt()
{
    printf("construct smart singleton and reference = %d/n", m_reference);
}

CSmartSt::~CSmartSt()
{
    printf("destroy smart singleton when reference = %d/n", m_reference);
}

void CSmartSt::doSomething(int test)
{
    printf("instance at (%8x) do something: %d!- Now reference is %d/n", _instance, test, m_reference);
}

CSmartSt *CSmartSt::Instance()
{
    if (!_instance)
    {
        _instance = new CSmartSt;
        static CDestroy clr;
    }
    //add reference cout by one
    InterlockedIncrement(&m_reference);
    return _instance;
}

void CSmartSt::SafeReleasse()
{
    //subtract reference cout by one
    InterlockedDecrement(&m_reference);
    if (m_reference <= 0)
    {
        delete _instance;
    }
}


CSafeSingleton::CSafeSingleton()
{
    m_Inst = CSmartSt::Instance();
    printf("construct CSafeSingleton, reference is %d/n", CSmartSt::m_reference);
}

CSafeSingleton::~CSafeSingleton()
{
    CSmartSt::SafeReleasse();
    printf("destroy CSafeSingleton, reference is %d/n", CSmartSt::m_reference);
}

CSmartSt* CSafeSingleton::Inst()
{
    return m_Inst;
}




void Use1()
{
    CSafeSingleton sc;
    sc.Inst()->doSomething(1);
}

void Use2()
{
    CSafeSingleton sc;
    sc.Inst()->doSomething(2);
}


void Test()
{
    CSafeSingleton globalst;
    globalst.Inst()->doSomething(0);

    Use1();

    Use2();
}

int _tmain(int argc, _TCHAR* argv[])
{
    //asset a instance, it is alive all along the programe life.
    Use1();

    Use2();

    return 0;
}

现在main函数不用再特别实例化gloable型的单件了,因为单件自动构造了一个内嵌清除器。
CSmartSt *CSmartSt::Instance()
{
    if (!_instance)
    {
        _instance = new CSmartSt;
        static CDestroy clr;
    }
    //add reference cout by one
    InterlockedIncrement(&m_reference);
    return _instance;
}






   
原创粉丝点击