作者:燕门雪_346 | 来源:互联网 | 2023-10-12 14:50
单例模式,是GOF 23种设计模式中的一种,有2种方法可以实现单例模式,分为懒汉式、饿汉式,它们的区别如下:
对比 | 懒汉式单例 | 饿汉式单例 |
---|
创建时间 | 需要时才创建,在程序运行之后调用getInstance()创建的 | 在程序编译时,就创建了单例对象 |
是否加锁 | 需要加锁 | 不需要加锁 |
线程安全 | 使用std::call_one、static member等方法,可以规避线程安全问题 | 在主函数之前,静态初始化,可以保证线程安全 |
实现难度 | 比较复杂 | 比较简单 |
1、懒汉式单例
这里采用可调用函数std:call_one()来保证单例只创建一次,从而保证线程安全。
//singleton.cpp
#include
#include
#include using namespace std;static std::once_flag g_flag;
class Singelton {
public:static Singelton* getInstance() {if (m_instance == NULL) {std::call_once(g_flag, initSingleton);}m_count++;return m_instance;}int getCount(){return m_count;}~Singelton(){if (m_instance != NULL) {delete m_instance;m_instance = NULL;}}private:Singelton(){m_instance = NULL;m_count = 0;cout << "call Singleton()..." << endl;}static void initSingleton(){m_instance = new Singelton;}static Singelton* m_instance;static int m_count;
};
Singelton *Singelton::m_instance = NULL;
int Singelton::m_count = 0;
2、饿汉式单例
通过静态初始化,在进入main()函数之前,单例就已经创建了,天然就具有线程安全性。
//singleton2.cpp
class Singelton2 {
public:static Singelton2* getInstance(){m_count++;return m_instance;}int getCount(){return m_count;}~Singelton2(){if (m_instance != NULL) {delete m_instance;m_instance = NULL;}}private:Singelton2(){m_instance = NULL;m_count = 0;}static Singelton2* m_instance;static int m_count;
};
Singelton2* Singelton2::m_instance = new Singelton2;
int Singelton2::m_count = 0;
3、完整代码
//single.cpp
#include
#include
#include using namespace std;static std::once_flag g_flag;
class Singelton {
public:static Singelton* getInstance() {if (m_instance == NULL) {std::call_once(g_flag, initSingleton);}m_count++;return m_instance;}int getCount(){return m_count;}~Singelton(){if (m_instance != NULL) {delete m_instance;m_instance = NULL;}}private:Singelton(){m_instance = NULL;m_count = 0;cout << "call Singleton()..." << endl;}static void initSingleton(){m_instance = new Singelton;}static Singelton* m_instance;static int m_count;
};
Singelton *Singelton::m_instance = NULL;
int Singelton::m_count = 0;
class Singelton2 {
public:static Singelton2* getInstance(){m_count++;return m_instance;}int getCount(){return m_count;}~Singelton2(){if (m_instance != NULL) {delete m_instance;m_instance = NULL;}}private:Singelton2(){m_instance = NULL;m_count = 0;}static Singelton2* m_instance;static int m_count;
};
Singelton2* Singelton2::m_instance = new Singelton2;
int Singelton2::m_count = 0;int main(){Singelton *singer = Singelton::getInstance();cout << "call times:"<<singer->getCount() << endl;Singelton *singer2 = Singelton::getInstance();cout << "call times:" << singer2->getCount() << endl;if (singer == singer2) {cout << "1.1 These two singes are the same!" << endl;}else {cout << "1.2 These two singes are not the same!" << endl;}Singelton2 *singer3 = Singelton2::getInstance();cout << "call times:" << singer3->getCount() << endl;Singelton2 *singer4 = Singelton2::getInstance();cout << "call times:" << singer4->getCount() << endl;if (singer3 == singer4) {cout << "2.1 These two singes are the same!" << endl;}else {cout << "2.2 These two singes are not the same!" << endl;}system("pause");return 0;
}
效果如下:
图(1) 单例模式的2种创建方法