简述
单例模式是设计模式中最简单的形式之一。其目的是使得类的一个对象成为系统中的唯一的实例。
这种模式设计到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象的方式,可以直接访问,不需要实例化该类的对象。
要点
单例模式的要点有三个:
单例模式有且仅有一个实例
单例类必须自行创建自己的唯一示例
单例类必须给所有其他对象提供这个示例
从具体实现角度来说,可分为以下三点:
提供一个private构造函数(防止外部调用而构造类的实例)
提供一个该类的static private对象
提供一个static public函数,用于创建或获取其本身的静态私有对象(例如:GetInstance())
除此之外,还有一些关键点(需要多加注意,很容易忽视):
线程安全(双检锁-DCL,即:double-checked locking)
资源释放
实现方法:
第一种:
#include <iostream>
#include <mutex>//使用局部变量,返回指针
class SignalInstance
{
public:
static SignalInstance* GetInstance()
{
static SignalInstance ins;
return &ins;
}
void disp()
{
std::cout << "hello Signal" << std::endl;
}
private:
SignalInstance() {}
};
第二种:
#include <iostream>
#include <mutex>
class SignalInstance
{
public:
static SignalInstance* GetInstance() // 一个公有的静态函数,调用构造函数,获取静态的类对象的指针
{
std::unique_lock<std::mutex> ulk(m_mutex); //加锁,防止多线程中出现不是单例的情况
if (m_sni == nullptr)
{
m_sni = new SignalInstance();
}
return m_sni;
}
void disp() // 一个普通的测试函数
{
std::cout << "hello Instance" << std::endl;
}
private:
static SignalInstance *m_sni; //静态函数只能调用静态的成员变量
static std::mutex m_mutex;
class Fre // 在类的内部创建一个私有的类,专门用作 对象的释放,当函数返回时,会自动调用它的析构函数,从而释放单例对象
{
public:
~Fre()
{
if (m_sni != nullptr)
{
delete m_sni;
m_sni = nullptr;
}
}
static Fre fr;
};
private:
SignalInstance() {} // 将构造函数写为私有方法,防止其他类的调用
};
SignalInstance* SignalInstance::m_sni = nullptr;
SignalInstance::Fre SignalInstance::Fre::fr; // 为了自动,必须要这句,否则无法析构
std::mutex SignalInstance::m_mutex;
// 测试代码
int main()
{
SignalInstance *ins = SignalInstance::GetInstance();
ins->disp();
getchar();
return 0;
}