设计模式之 单例模式

介绍

几个重点:

  • 构造函数为private
  • 提供一个获取单例对象指针的函数
  • 一个静态指针成员存储单例对象

注意:

  • 获取单例对象也可以获取对象引用,但要注意拷贝构造函数和赋值运算符
  • 如果有多线程访问单例,需要注意线程同步

 

UML类图:

简单示例:

懒汉和饿汉模式:

#ifndef SIMPLE_SINGLETON_H
#define SIMPLE_SINGLETON_H

#include <iostream>
using namespace std;

/**
 * @brief The LazySingleton class
 * 懒汉模式
 */
class LazySingleton
{
public:
    static LazySingleton *getInstance()
    {
        if( m_instance == nullptr)
            m_instance = new LazySingleton;

        return  m_instance;
    }

    static void freeInstance()
    {
        if( m_instance != nullptr )
            delete  m_instance;

        m_instance = nullptr;
    }
private:
    LazySingleton()
    {
        cout<<" LazySingleton 构造函数执行"<<endl;
    }
    static LazySingleton *m_instance ;
};
LazySingleton *LazySingleton::m_instance = nullptr;


/**
 * @brief The HungrySingleton class
 * 饿汉模式,一般用不到
 */
class  HungrySingleton
{
public:
    static HungrySingleton *getInstance()
    {
        if( m_instance == nullptr)
            m_instance = new HungrySingleton;

        return  m_instance;
    }

    static void freeInstance()
    {
        if( m_instance != nullptr )
            delete  m_instance;

        m_instance = nullptr;
    }
private:
    HungrySingleton()
    {
        cout<<" HungrySingleton 构造函数执行"<<endl;
    }
    static HungrySingleton *m_instance ;
};
HungrySingleton *HungrySingleton::m_instance = new HungrySingleton;

#endif // SIMPLE_SINGLETON_H

懒汉线程安全模式:

#ifndef THREAD_SINGLETON_H
#define THREAD_SINGLETON_H

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;


void printids(const char *s)
{
    pid_t pid;
    pthread_t tid;
    pid = getpid();
    tid = pthread_self();
    printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int) pid,
           (unsigned int) tid, (unsigned int) tid);
}




class LazySingleton
{
public:
    static LazySingleton *getInstance()
    {

//        if( m_instance == nullptr)
//        {
//            m_count++;
//            m_instance = new LazySingleton;
//        }

        if( m_instance == nullptr)
        {
            pthread_mutex_lock(&m_mutex_lock);

             if( m_instance == nullptr)
             {
                 m_count++;
                 m_instance = new LazySingleton;
             }

            pthread_mutex_unlock(&m_mutex_lock);
        }



        return  m_instance;
    }

    static void freeInstance()
    {
        if( m_instance != nullptr )
            delete  m_instance;

        pthread_mutex_destroy(&m_mutex_lock);
        m_instance = nullptr;
    }

    void showMessage()
    {
        cout<<"LazySingleton message!"<<endl;
    }
private:
    LazySingleton()
    {


        cout<<" LazySingleton 构造函数执行开始"<<endl;
        sleep(2);
        cout<<" LazySingleton 构造函数执行 ["<<m_count<<"] 次"<<endl;
    }
    static LazySingleton *m_instance ;
    static int m_count;
    static pthread_mutex_t m_mutex_lock;
};
LazySingleton *LazySingleton::m_instance = nullptr;
int LazySingleton::m_count = 0;
pthread_mutex_t LazySingleton::m_mutex_lock = PTHREAD_MUTEX_INITIALIZER;


void *thr_fn(void *arg)
{
   // printids("new thread: ");

    LazySingleton::getInstance()->showMessage();
    return nullptr;
}

#endif // THREAD_SINGLETON_H

线程安全,调用方式: 

 printids("main thread:");
    int err;
    pthread_t ntid[3];
    for (int i=0 ; i<3 ; i++) {
        err = pthread_create(&ntid[i], NULL, thr_fn, NULL);
        if (err != 0)
            printf("can't create thread: %s\n", strerror(err));


    }
    for (int i=0; i < 3 ; i++) {
        pthread_join(ntid[i],NULL);
    }

内部静态类(懒汉)方式:


class  StackSingleton
{
public:
    static StackSingleton *getInstance()
    {
        //内部静态实例的懒汉模式
        pthread_mutex_lock(&m_mutex_lock);
        static StackSingleton _instance ;
        pthread_mutex_unlock(&m_mutex_lock);
        return  &_instance;
    }

    void printS()
    {
        cout<<"栈方式的单例模式..."<<endl;
    }


private:
    StackSingleton()
    {
        cout<<" StackSingleton 构造函数执行"<<endl;
    }

    static pthread_mutex_t m_mutex_lock;

};
pthread_mutex_t StackSingleton::m_mutex_lock = PTHREAD_MUTEX_INITIALIZER;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liu-Eleven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值