单例模式存在的意义是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
懒汉示例如下:
#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; }