线程安全的单例模式的实现

C++编程语言是一个应用广泛的计算机应用语言,它功能强大,在一定程度上大大提高了程序开发效率。C++单例模式也称为单件模式、单子模式。使用单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出等。

单例模式有许多种实现方法,在C++中,甚至可以直接用一个全局变量做到这一点,但这样的代码显得很不优雅。定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有静态方法获取该实例。实现如下



#include "stdafx.h"

#include <iostream>
#include <memory>
#include <string>
#include <boost/thread/mutex.hpp>
using namespace std;


#define DISALLOW_COPY(ClassName) \
    ClassName(const ClassName &)
#define DISALLOW_ASSIGN(ClassName) \
    ClassName &operator = (const ClassName &)
#define DISALLOW_COPY_AND_ASSIGN(ClassName) \
    DISALLOW_COPY(ClassName);               \
    DISALLOW_ASSIGN(ClassName)               // no semicolon here


class ClassA
{
public:
    typedef std::shared_ptr<ClassA> ClassAPtr;
    static ClassAPtr Instance(void);
    ~ClassA(void);


    void SetAddress(const std::string &);
    const std::string &GetAddress(void) const;
private:
    std::string m_sAddr;
    mutable boost::mutex         m_mAddr;


    static ClassAPtr s_gClassAPtr;
    static boost::mutex          s_gMtxAssn;
    ClassA(void);
    DISALLOW_COPY_AND_ASSIGN(ClassA);
};


ClassA::ClassAPtr ClassA::s_gClassAPtr;
boost::mutex      ClassA::s_gMtxAssn;


ClassA::ClassAPtr ClassA::Instance(void)
{
    try
    {
        boost::mutex::scoped_lock lckAssgn(s_gMtxAssn);


        if (nullptr == s_gClassAPtr)
        {
            s_gClassAPtr = ClassAPtr(new ClassA);
        }
    }
    catch(const std::bad_alloc &KE)
    {
        std::cout<<KE.what()<<std::endl;
        return ClassAPtr();
    }
    catch(...)
    {
        std::cout<<"Failed to get ClassA instance with unknown error"<<std::endl;
        return ClassAPtr();
    }
    return s_gClassAPtr;
}


ClassA::ClassA(void)
try : m_sAddr()
{


}
catch(...)
{


}


ClassA::~ClassA(void)
{


}


void ClassA::SetAddress(const std::string &ksAddr)
{
    try
    {
        boost::mutex::scoped_lock lckAssgn(m_mAddr);
        m_sAddr = ksAddr;
    }
    catch(...)
    {
        std::cout<<"Fail to copy address string"<<std::endl;
    }
}


const std::string &ClassA::GetAddress(void) const
{
    try
    {
        boost::mutex::scoped_lock lckAssgn(m_mAddr);
        return m_sAddr;
    }
    catch(...)
    {
        std::cout<<"Fail to get address string\n";
        throw;
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
    try
    {
        ClassA::ClassAPtr pClassA = ClassA::Instance();
        if (nullptr == pClassA)
        {
            return -1;
        }
        std::string sSet("aa");
        pClassA->SetAddress(sSet);
        std::string sGet = pClassA->GetAddress();
        std::cout<<sGet<<std::endl;


        ClassA::ClassAPtr pClassA1 = ClassA::ClassAPtr();
        if (nullptr == pClassA1)
        {
            std::cout<<"pClassA1 is nullptr\n";
        }
    }
    catch(...)
    {
        return -1;
    }
    
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值