单例模式简要学习

来源:互联网 发布:中山大学图书馆 知乎 编辑:程序博客网 时间:2024/05/01 03:35

单例模式是一种常用的软件设计模式,它的核心只包含一个被称为单例模式的特殊类,通过单模式可以保证系统中的一个类中只有一个实例。



单例模式也叫作单件模式,Singleton还是一种非常有用 设计模式,几乎所有稍微大一些的程序都会使用它,所以构建一个线程安全并且高效的Singleton神重要

1.单例类保证全局只有一个唯一实例对象

2.单例类提供获取这个唯一实例的接口。


第一种实现形式:不考虑线程安全的一个单例类

<span style="font-family:Microsoft YaHei;font-size:24px;">class Singleton{public:static Singleton* GetInsatnce(){//双重检测,第一次进入时,if (_sInstace== NULL){if (_sInstace == NULL){_sInstace = new Singleton();}}return _sInstace;}static void DelInstance(){if (_sInstace){delete _sInstace;_sInstace = NULL;}}void Print(){cout << _data << endl;}private:Singleton():_data(10){}Singleton& operator=(const Singleton);static Singleton* _sInstace;int _data;};Singleton* Singleton::_sInstace = NULL;</span>
第二种实现方式:

方法:利用RAII 和memoryBarrier等技术保证线程安全和资源的有效保证。

<span style="font-family:Microsoft YaHei;font-size:24px;">#include<mutex>#include<Windows.h>//内存栅栏的memoryBarrier的头文件class Singleton{public:struct GC//RAII 资源获得并初始化{//因为是全局变量,所以析构的时候在main之后进行析构。线程安全public:~GC(){cout << "GC::~GC" << endl;DelInstance();}};public:static Singleton* GetInstance(){lock_guard<mutex> lck(mtx);if (_sInstance == NULL){//双重检查,避免每次进入函数时都要加锁,提高效率if (_sInstance == NULL){Singleton* tmp = new Singleton();//new包含三个步骤,1.申请空间2.调用构造函数//进行初始化,3.将右边的值赋值给左边。//内存栅栏--防止栅栏后面的赋值重排到栅栏之前MemoryBarrier();//防止指令重排,编译器进行优化,防止栅栏后面的赋值重排//到栅栏的前面。_sInstance = tmp;}}return _sInstance;}static void DelInstance(){lock_guard<mutex> lck(mtx);//lock_guardif (_sInstance){delete _sInstance;_sInstance = NULL;}}void Print(){cout << _a << endl;}private:Singleton():_a(10){}Singleton(const Singleton&);Singleton& operator=(const Singleton&);static Singleton* _sInstance;static mutex mtx;int _a;};Singleton* Singleton::_sInstance = NULL;mutex Singleton::mtx;Singleton::GC gc;</span>

第三中实现方法:饿汉模式


思路:并未进行加锁,但在某些情况下会有错误,若在构造函数中创建线程,因为在main函数之前调用,所以各种程序环境并未准备好,会出现错误。

<span style="font-family:Microsoft YaHei;font-size:24px;">#include<assert.h>class Singleton{public://static Singleton* GetInstance()//{//static Singleton sInstance;//return &sInstance;//}static Singleton* GetInstance(){assert(_sInstance);//assert断言,如果_sInstance不为空return _sInstance;//返回唯一的_sInstance}void Print(){cout << _a << endl;}static void DelInstance(){//删除函数if (_sInstance){delete _sInstance;_sInstance = NULL;}}private://将构造函数,拷贝构造,赋值运算符重载私有化Singleton():_a(10){}Singleton(const Singleton&);Singleton& operator=(const Singleton&);static Singleton* _sInstance;//私有化数据int _a;};Singleton* Singleton::_sInstance = new Singleton;//类外进行初始化。int main(){//Singleton s1;//不能通过构造函数进行构造,构造函数为私有函数Singleton::GetInstance()->Print();system("pause");return 0;  }</span>



1 0
原创粉丝点击