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;
}