单例模式

“保证一个类仅有一个实例,并提供一个访问它的全局访问点“

1.类图:

2.懒汉式

代码:

#include <iostream>
using namespace std;

// 懒汉式
class Singleton
{
public:
    static Singleton *getInstance()
    {
        if (_instance == NULL)
        {
            _instance = new Singleton();
        }
        return _instance;
    }

    static void releaseInstance()
    {
        if (_instance != NULL)
        {
            delete _instance;
            _instance = NULL;
        }
    }
    
private:
    Singleton(){ }
    ~Singleton(){ } //防止外部多次delete同一块内存
    Singleton(const Singleton &other) {  }  // 禁止拷贝构造
    Singleton &operator=(const Singleton& other) { } //禁止外部使用=操作符重载,改变已有对象
    
    static Singleton *_instance;
};

Singleton *Singleton::_instance = NULL;

3.饿汉式

代码:

#include <iostream>
using namespace std;

class Singleton
{
public:
    static Singleton *getInstance()
    {
        return _instance;  //直接返回静态实例
    }

    static void releaseInstance()
    {
        if (_instance != NULL)
        {
            delete _instance;
            _instance = NULL;
        }
    }

private:
    Singleton(){ cout << "Singleton called" << endl; }
    ~Singleton(){ } //防止外部多次delete同一块内存
    Singleton(const Singleton &other) {  }  // 禁止拷贝构造
    Singleton &operator=(const Singleton& other) { } //禁止外部使用=操作符重载,改变已有对象

    static Singleton *_instance;
};

Singleton *Singleton::_instance = new Singleton();

void test()
{
    Singleton *s1 = Singleton::getInstance();
    Singleton *s2 = Singleton::getInstance();
    cout << s1 << endl;
    cout << s2 << endl;
    Singleton::releaseInstance();
    Singleton::releaseInstance();
}

4.懒汉式遇上多线程,需要同步

bug代码:

#include <iostream>
#include <Windows.h>
#include <process.h>
using namespace std;

class Singleton
{
private:
//构造函数不是线程安全函数 Singleton() { cout
<< "构造Singleton begin" << endl; Sleep(1000); //用来模拟多线程中对象的初始化可能耗时较长的情景 cout << "构造Singleton end" << endl; count++; //对象数加1 } public: static Singleton *getInstance() { if (_instance == NULL) { _instance = new Singleton; } return _instance; } static void releaseInstance() { if (_instance != NULL) { delete _instance; _instance = NULL; } } static int getCount() { return count; } private: static Singleton *_instance; static int count; ~Singleton(){ } Singleton(const Singleton& other){} Singleton &operator=(const Singleton& other) {} }; Singleton *Singleton::_instance = NULL; int Singleton::count = 0; //用来统计对象的个数 void threadFunc(void *) { Singleton::getInstance(); } void test() { HANDLE hThread[3]; for (int i = 0; i < 3; ++i) { hThread[i] = (HANDLE)_beginthread(threadFunc, 0, NULL); //创建线程 构造单例 } for (int i = 0; i < 3; ++i) { WaitForSingleObject(hThread[i], INFINITE); // 等待线程退出 } cout << "count: " << Singleton::getCount() << endl; } int main() { test(); cin.get(); return 0; }

效果:

在上面代码的基础上修改,加入同步机制:

加入:

#include <afxmt.h>  //需要右击项目,选择属性=>c/c++>预处理器>预处理定义添加_AFXDLL
static CCriticalSection cs; // 定义全局临界区

去掉:

#include <Windows.h>

修改getInstance()方法:

static Singleton *getInstance()
    {
        if (_instance == NULL) // 只有在_instance等于NULL的时候才开始时候加锁机制, 并进行二次检查
        {
            cs.Lock();
            if (_instance == NULL)
            {
                _instance = new Singleton;
            }
            cs.Unlock();
            
        }
        return _instance;
    }

效果:

原文地址:https://www.cnblogs.com/hupeng1234/p/6756121.html