C++中的单例设计模式

单例设计模式

首先我们要注意,单例设计是一种模式,也就是一种设计思想,可以让程序员减少bug,为什么这么说呢?因为单例模式,就是像框架一样,在设计程序的时候,采用别人经过多次的尝试而得出在设计软件时候该怎么做能有更好的结果,不容易出现错误,所以就有了一种设计思想,或者设计时候的框架,今天我们来讨论单例设计模式。

什么叫单例模式?

单例模式,我们从代码说起,就是在面向对象编程中,一个类只能实例化出来一个对象。

单例模式有什么用?

单例模式,在计算机中,当我们的某个类只允许创建一个对象的时候就可以用单例模式。这时候就有人疑问了,一个类怎么可能只要一个实例对象呢?我们举个列子,计算机系统,操作系统是我们计算机的管家,它也是一个软件,那么假设它是一个类,这时候就不允许创建两个对象,当然除过mac。

单例模式的实现

单例模式有两种实现方式,一种叫饿汉模式,一种是懒汉模式。两种实现方式不同,虽然实现的功能是一样,但是用途却有所差异,这就取决于使用的场景。

  • 饿汉模式
template<typename T> 
class SinglePattern
{
public:
    // 给外部提供静态的成员函数,属于本类,不属于某个对象
    static T* GetInit() 
    {   
        return &sit;
    }   
private:
    static T sit; // 静态成员变量,static函数只能访问static变量
};
string* result = SinglePattern<string>::GetInit();

在静态函数中存在一个静态的变量,所以每次调用GetInit()时候,就会返回静态成员变量的地址,所以都是同一个地址。就达到了只能实例一个对象的单例模式
使用场景
当需要在初始化后,要有很快的速度,运行要有很快的速度,我们就可以用饿汉模式,因为它是在初始化的时候已经开辟好了空间,所以就相对较快,而且饿汉模式是在栈上开辟空间,系统会自动释放空间不会造成内存泄漏。

  • 懒汉模式
    懒汉模式在代码书写上会比较麻烦,因为存在线程安全问题,要是你大笔一挥写出
    这样的代码:
template<typename T>
class SinglePatternS
{
public:
    static T* GetInit()
    {   
        if (sit == NULL)
        {   
            sit = new T;
        }  
        return sit;
    }   
private:
    static T* sit;
};

这样的代码,我们先来分析一下成员变量,c++是一门追求效率的语言,所以就做了很多的优化,但是有时候后就会适得其反,当我们声明成静态变量的时候,编译器会优化为寄存器变量,所以有时候我们拿到的数据可能不是预定想要的。所以第一点先加上volatile 来保存内存的可见性。第二,现在的代码当有多线程中,是不安全的。怎么理解?
首先我们就用两个线程来解释,当一个线程在运行到

if (sit == NULL)

后面时候,系统调度器切换了线程,这时候第二个线程也进入上面函数的if判断语句中,这时候,就有可能会new出两个对象,并且第二个会占用指针,这时第一创建的对象就内存泄漏,所以我们加上互斥所来防止发生这样的事
就有:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //初始化锁
template<typename T>
class SinglePatternS
{
public:
    static T* GetInit()   
    {   
        if (sit == NULL) // 优化效率
        {   
            pthread_mutex_lock(&mutex); //加锁
            if (sit == NULL)
            {   
                sit = new T;
            }   
            pthread_mutex_unlock(&mutex); // 解锁
        }   
        return sit;
    }   
private:
    static volatile T* sit;
};

我们可以用加锁的方式来防止线程安全问题,多加一个if判断,遮掩我们就能少去加锁解锁所产生的消耗。

如有错误,欢迎指正~

猜你喜欢

转载自blog.csdn.net/gangstudyit/article/details/81046467