2.单例模式
一、定义
确保一个类仅有一个唯一的实例,并且提供一个全局的访问点。
二、要解决的问题
- 独生子女
无论new了多少个对象,始终只存在一个实例 - 应用场景
对临界资源(例如日志、打印机)的访问
三、解决步骤
- 将构造函数声明成私有类型
- 声明一个类的静态实例
- 提供一个获得实例的方法
四、代码实现
4.1 实现方法1
下面这种方式存在以下问题
- 只提供了
getInstance
方法获取对象,没有提供释放函数 - 析构函数不会被运行
- 多线程调用
getInstance
时将不是线程安全的
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关键字在堆空间中申请内存,空间被自动管理
- 析构函数被自动执行
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();
}