C++单例模式(懒汉 & 饿汉)

单例模式存在的意义是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。


懒汉示例如下:

#ifndef SINGLETON_H
#define SINGLETON_H
#include <iostream>
#include <QMutex>
using namespace std;
//用户访问唯一实例的方法只有GetInstance()成员函数。
//如果不通过这个函数,任何创建实例的尝试都将失败,
//因为类的构造函数是私有或者保护的防止外部函数实例化。 GetInstance()使用懒惰初始化,
//也就是说它的返回值是当这个函数首次被访问时被创建的。
//这是一种防弹设计——所有GetInstance() 之后的调用都返回相同实例的指针:

class l_singleton
{
private:
   l_singleton(){
       cout<<"l_singleton"<<endl;
   }//用户访问唯一实例的方法只有GetInstance()成员函数因为类的构造函数是私有或者保护的防止外部函数实例化.
   static l_singleton *p;//Private防止其他人使用NEW
public:    
    static l_singleton *Getinstance();
    static QMutex mutex;
    void Hello();
};

#endif // SINGLETON_H

#include "l_singleton.h"

//类内static变量要初始化
l_singleton *l_singleton::p = NULL;
QMutex l_singleton::mutex;

//考虑两个线程同时首次调用instance方法且同时检测到p是NULL值,
//则两个线程会同时构造一个实例给p,这是严重的错误,要加锁!!!
l_singleton *l_singleton::Getinstance(){
    if(NULL == p){

        mutex.lock();
        if(NULL == p){
            p = new l_singleton();
        }
       mutex.unlock();
    }
   return p;
}

/*内部静态变量的懒汉实现,没有new无需delete
l_singleton *l_singleton::Getinstance(){

        mutex.lock();
        static l_singleton obj;
        mutex.unlock();
        return &obj;
}
*/

void l_singleton::Hello(){

    cout<<"Hello world!"<<endl;
}


饿汉示例如下:

#ifndef E_SINGLETON_H
#define E_SINGLETON_H
#include <iostream>
using namespace std;


class e_singleton
{
private:
    e_singleton(){
        cout<<"e_singleton"<<endl;
    }//为了使得对象唯一,还需要将构造函数设为私有
    static e_singleton *p;
public:
    static e_singleton *Getinstance();
    void Hello();
};

#endif // E_SINGLETON_H

#include "e_singleton.h"

//饿汉单例,即在最开始的时候,静态对象就已经创建完成;
//设计方法是类中包含一个静态成员指针,该指针指向该类的一个对象,
//提供一个公有的静态成员方法,返回该对象指针;为了使得对象唯一,还需要将构造函数设为私有
e_singleton *e_singleton::p = new e_singleton;

e_singleton * e_singleton::Getinstance(){

    return p;
}

void e_singleton::Hello(){

    cout<<"Hello Kitty !"<<endl;
}


e_singleton调用头文件即实例化对象

l_singleton需要使用特定实例对象函数

#include <iostream>
#include <l_singleton.h>
#include <e_singleton.h>

/*

  单例两种实现方法:懒汉与饿汉。

懒汉:故名思义不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化.
内部静态变量的懒汉实现,在instance函数里定义一个静态的实例,在返回时只需要返回其指针就可以了。

饿汉:饿了肯定要饥不择食。所以在单例类定义的时候就进行实例化。

    特点与选择:

由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。
在访问量较小时,采用懒汉实现。这是以时间换空间。

*/

int main()
{
    //验证无法外部创建实例。
    //l_singleton obj;

    /*懒汉模式:调用共有的静态成员方法
    l_singleton* p1 = l_singleton :: GetInstance();
    l_singleton* p2 = p1->GetInstance();
    l_singleton & ref = * l_singleton :: GetInstance();
    */
    l_singleton *obj = l_singleton::Getinstance();
    obj->Hello();
    delete obj;

    /*饿汉模式:调用共有的静态成员方法
    e_singleton* p1 = e_singleton :: GetInstance();
    e_singleton* p2 = p1->GetInstance();
    e_singleton & ref = * e_singleton :: GetInstance();
    */
    //e_singleton *obj1 = e_singleton::Getinstance();
    //obj1->Hello();
    


    return 0;
}


猜你喜欢

转载自blog.csdn.net/yuanchunsi/article/details/79844121