诉求:希望我们的 class 只有一个对象
源码解析
class CLbTransfLog
{
public:
~CLbTransfLog(void)
{
}
static CLbTransfLog* GetInstancePtr(void)
{
static CLbTransfLog m_sLBIMLog;
return &m_sLBIMLog;
}
private:
CLbTransfLog(void)
: m_strLogFileName(_T(""))
, m_strDBLogFileName(_T(""))
{
}
CLbTransfLog(const CLbTransfLog& other);
}
这是一个单例模式的实现。单例模式是一种创建型设计模式,用于确保一个类只有一个实例,并提供一个访问该实例的全局访问点。
单例模式的一般特点
这段代码也可以反映单例模式的一般特点
-
类的构造函数是私有的
CLbTransfLog类的构造函数是私有的,因此外部无法直接创建该类的对象。 -
提供一个访问类实例的全局访问点
这里提供了一个静态的
GetInstancePtr()方法,用于获取CLbTransfLog类的唯一实例。 -
使用 static 创建静态局部变量
GetInstancePtr()方法内部使用静态局部变量实现了惰性初始化,确保仅在首次调用该方法时才会创建实例。并且这个对象 static CLbTransfLog m_sLBIMLog;它不属于任何一个类的对象,从创建的一刻,就在内存中某一个区域就存在了,并且只有一份。因此,无论多少次调用
GetInstancePtr()方法,它都返回同一个实例的指针。
这种实现方式的好处在于,它可以确保系统中只有一个 CLbTransfLog 类的实例,从而避免了实例的重复创建和资源浪费。此外,它还提供了一个全局访问点,使得任何地方都可以访问到该实例,方便了程序的编写和管理。
我们还看见过下面的写法
class CLbTransfLog
{
public:
~CLbTransfLog(void)
{
}
static CLbTransfLog& GetInstancePtr
{
return m_sLBIMLog;
}
void setup(){...};
private:
CLbTransfLog(void)
: m_strLogFileName(_T(""))
, m_strDBLogFileName(_T(""))
{
}
CLbTransfLog(const CLbTransfLog& other);
static CLbTransfLog& m_sLBIMLog;
}
这种写法是在没有人创建 CLbTransfLog 对象的时候,CLbTransfLog 就有一个变量了,占有一个空间了。
不想让外界创建 CLbTransfLog ,就把他的构造函数放在 private 中。
外界只能通过静态函数 GetInstancePtr 函数,获取到唯一的 m_sLBIMLog,接下来就可以通过唯一的 m_sLBIMLog,获取类中的各种函数了,比如,m_sLBIMLog.setup()。
可以看出来这种写法有一个缺点,如果外界没有用到这个类,这个类的静态变量仍然存在,这就有一点浪费,所以更好的写法还是第一种。
两种写法的区别
这两种写法的区别在于,第二种写法将 m_sLBIMLog 定义为静态局部变量,外界没有使用这个类的时候,这个类的静态变量仍然存在。而第一种写法将 m_sLBIMLog 定义为静态成员变量,并通过类外部的创建来初始化它,如果外界没有人使用这个类,将不会创建这个单例。
单例模式模板总结
第一种(更好,自己编码使用)
class A
{
public:
static A& getInstance();
setup(){...}
...
private:
A(); // 类私有构造函数
A(const A& rhs);
...
}
A& A::getInstance()
{
static A a; // 期望只有一份的类实例
return a;
}
指针形式
class A
{
public:
static A* getInstance();
setup(){...}
...
private:
A(); // 类私有构造函数
A(const A& rhs);
...
}
A* A::getInstance()
{
static A a; // 期望只有一份的类实例
return &a;
}
第二种(会识别)
class A
{
public:
static A& getInstance() {return a;};
setup(){...};
...
private:
A(); // 类私有构造函数
A(const A& rhs);
static A a; // 期望只有一份的类实例
...
}
指针的形式
class A
{
public:
static A* getInstance();
static void releaseInstance();
private:
A();
~A();
private:
static A* m_pInstance;
}
A* A::m_pInstance = nullptr;//定义,赋初值
A* A::getInstance()
{
if (nullptr == m_pInstance)
{
m_pInstance = new A();
}
return m_pInstance;
}
void A::ReleaseInstance()
{
if (nullptr != m_pInstance)
{
delete m_pInstance;
m_pInstance = nullptr;
}
}