一、定义
确保一个类仅有一个唯一的实例,并且提供一个全局的访问点。
二、要解决的问题
- 独生子女
无论new了多少个对象,始终只存在一个实例 - 应用场景
对临界资源(例如日志、打印机)的访问
三、解决步骤
- 将构造函数声明成私有类型
- 声明一个类的静态实例
- 提供一个获得实例的方法
四、代码实现
4.1 实现方法1
下面这种方式存在以下问题
- 只提供了
getInstance
方法获取对象,没有提供释放函数 - 析构函数不会被运行
- 多线程调用
getInstance
时将不是线程安全的
cpp
class Singleton
{
private:
static Singleton* singleton; //实例对象为私有
Singleton() //构造方法为私有
{
std::cout << "Singleton" << std::endl;
}
~Singleton()
{
std::cout << "~Singleton" << std::endl;
}
public:
static Singleton& getInstance()
{
if (!singleton)
{
singleton = new Singleton();
}
return *singleton;
}
void printAddress()
{
printf("%p\n", this);
}
};
Singleton* Singleton::singleton = nullptr;
4.2 实现方法2
改进点
- 禁止单例模式的拷贝和赋值
- 采用
局部静态变量
的方式返回,线程安全(c++11及以后) - 没有采用new关键字在堆空间中申请内存,空间被自动管理
- 析构函数被自动执行
cpp
class Singleton
{
private:
Singleton() //构造方法为私有
{
std::cout << "Singleton" << std::endl;
}
~Singleton()
{
std::cout << "~Singleton" << std::endl;
}
//禁止拷贝和赋值
Singleton(const Singleton& obj) = delete;
Singleton& operator=(const Singleton& obj) = delete;
public:
static Singleton& getIntance()
{
static Singleton instance;
return instance;
}
void printAddress()
{
printf("%p\n", this);
}
};
int main()
{
Singleton::getIntance().printAddress();
Singleton::getIntance().printAddress();
}