关于单例模式的细节学习——C++实现版

单例模式可以说是最普为人知的一种设计模式了吧,但单例模式的细节又有多少人想清了呢?

那就先提几个问吧

单例模式的对象该如何释放?何时释放?如何优雅的释放?
单例模式有哪几种实现方式?
如果你瞬间就一大段代码涌出脑海,我建议你别看这篇博文了,省得浪费你时间。
那下面就开始说正事吧

UML图

这里写图片描述

饿汉式

时间换取空间的实现方式,打死我也不创建对象。这种模式只有在第一个对象实例化的时候才会创建对象,但实现起来稍微麻烦一些,要考虑到多线程的场景。

hungry_singleton_mode.h
#ifndef _SINGLETON_
#define _SINGLETON_

#include "string"
#include "iostream"
using namespace std;

class myself
{
private:
    static myself *m_me;
    static pthread_mutex_t mutex;
    string m_attribuate;
    myself(string attr)
    {
        m_attribuate = attr;
    }
    //嵌套类实现自释放单例对象
    class clean_up
    {
    public:
        ~clean_up()
        {
            if (m_me != NULL)
            {
                cout << "myself distruction." << endl;
                delete m_me;
                m_me = NULL;
            }
        }
    };
    static clean_up m_clean;
public:
    static myself* get_instance(string attr)
    {
        //直接加锁性能不佳
        if (m_me == NULL)
        {
            pthread_mutex_lock(&mutex);
            if (m_me == NULL)
            {
                m_me = new myself(attr);
            }
            pthread_mutex_unlock(&mutex);
        }
        return m_me;
    }
    string show_attr()
    {
        return m_attribuate;
    }
};

#endif 

hungry_singleton_mode.cpp
#include "iostream"
#include "pthread.h"
#include "hungry_singleton_mode.h"

using namespace std;

pthread_mutex_t myself::mutex = PTHREAD_MUTEX_INITIALIZER;
myself* myself::m_me = NULL;   //饿汉式
myself::clean_up myself::m_clean;  //初始化构造内部类对象

int main(int argc, char const *argv[])
{
    myself *p_me = myself::get_instance("I'm a lonely gambler.");
    myself *p_me2 = myself::get_instance("my English is poor.");
    cout << p_me->show_attr() << endl;
    cout << p_me2->show_attr() << endl;
    return 0;
}

输出结果

这里写图片描述

懒汉式

空间换时间的方法,一开始初始化的时候便创建对象,所以不用考虑多线程场景下线程同步的问题,故实现相对较简单。

#include <iostream>

using namespace std;

class myself
{
private:
    static myself* m_me;
    string m_attr;
    myself(string attr)
    {
        m_attr = attr;
    }
    class clean_up
    {
    public:
        ~clean_up()
        {
            if (m_me != NULL)
            {
                cout << "myself destruction." << endl;
                delete m_me;
                m_me = NULL;
            }
        }
    };
    static clean_up m_clean;
public:
    static myself* get_instance()
    {
        return m_me;
    }
    string show_attr()
    {
        return m_attr;
    }
};

myself* myself::m_me = new myself("hello world.");
myself::clean_up myself::m_clean;

int main(int argc, char const *argv[])
{
    myself *p_me = myself::get_instance();
    cout << p_me->show_attr() << endl;
    return 0;
}

输出结果

这里写图片描述

单例模式的对象如何优雅的释放

通过内部类的形式实现单例模式的对象自动释放,具体代码如上。但是切记内部类的对象开始需要初始化。

猜你喜欢

转载自blog.csdn.net/LonelyGambler/article/details/81273245