作者:燕门雪_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种创建方法