单例模式
来源:互联网 发布:淘宝直通车排名规则 编辑:程序博客网 时间:2024/05/31 15:18
比较几种常见的单例模式实现
方法一:
#include<iostream>using namespace std;class Singleton{private:Singleton():Data(0) //构造函数声明为私有{}static Singleton * Instance;public:static Singleton & GetInstance();int Data;//用于测试};Singleton * Singleton::Instance=NULL;Singleton & Singleton::GetInstance(){if(Instance == NULL) //判断是否实例已经存在{Instance = new Singleton();}return *Instance;}int main(void){Singleton& singletonObj1=Singleton::GetInstance();cout<<singletonObj1.Data<<endl;singletonObj1.Data=1;cout<<singletonObj1.Data<<endl;Singleton& singletonObj2=Singleton::GetInstance();cout<<singletonObj2.Data<<endl;//通过观测此次输出的结果可知,singletonObj1与singletonObj2是同一对象singletonObj2.Data=2;cout<<singletonObj2.Data<<endl;return 0;}方法一是最基本的实现了单例模式。方法二:
#include<iostream>using namespace std;class Singleton{private:Singleton():Data(0) //构造函数声明为私有{}static Singleton * Instance;public:static Singleton & GetInstance();int Data;//用于测试};Singleton * Singleton::Instance=NULL;Singleton & Singleton::GetInstance(){if(Instance == NULL) //判断是否实例已经存在{lock();//需要另外实现if (Instance==NULL){Instance = new Singleton();}unlock();//需要另外实现}return *Instance;}int main(void){Singleton& singletonObj1=Singleton::GetInstance();cout<<singletonObj1.Data<<endl;singletonObj1.Data=1;cout<<singletonObj1.Data<<endl;Singleton& singletonObj2=Singleton::GetInstance();cout<<singletonObj2.Data<<endl;//通过观测此次输出的结果可知,singletonObj1与singletonObj2是同一对象singletonObj2.Data=2;cout<<singletonObj2.Data<<endl;return 0;}
方法二相对于方法一,增加了多线程安全
方法三:
#include<iostream>using namespace std;class Singleton{private:Singleton():Data(0) //构造函数声明为私有{}static Singleton * Instance;public:static Singleton & GetInstance();int Data;//用于测试};Singleton * Singleton::Instance=new Singleton();Singleton & Singleton::GetInstance(){return *Instance;}int main(void){Singleton& singletonObj1=Singleton::GetInstance();cout<<singletonObj1.Data<<endl;singletonObj1.Data=1;cout<<singletonObj1.Data<<endl;Singleton& singletonObj2=Singleton::GetInstance();cout<<singletonObj2.Data<<endl;//通过观测此次输出的结果可知,singletonObj1与singletonObj2是同一对象singletonObj2.Data=2;cout<<singletonObj2.Data<<endl;return 0;}方法三的实例在程序启动时就已经创建,因此在每次获取的时候就不需要进行任何的判断。
方法四:
#include<iostream>
using namespace std;class Singleton{private:Singleton():Data(0) //构造函数声明为私有{}//Singleton(const Singleton&);//Singleton& operator=(const Singleton&);public:static Singleton & GetInstance();int Data;//用于测试};Singleton & Singleton::GetInstance(){static Singleton Instance;return Instance;}int main(void){Singleton& singletonObj1=Singleton::GetInstance();cout<<singletonObj1.Data<<endl;singletonObj1.Data=1;cout<<singletonObj1.Data<<endl;Singleton& singletonObj2=Singleton::GetInstance();cout<<singletonObj2.Data<<endl;//通过观测此次输出的结果可知,singletonObj1与singletonObj2是同一对象singletonObj2.Data=2;cout<<singletonObj2.Data<<endl;return 0;}方法四将实例指定为静态局部变量,它是在第一次调用Singleton::GetInstance()时创建。其为局部静态变量,不是new出来的,在程序结束时能自动销毁,不用delete。但是其存在的一个问题就是,如果不是用引用调用此静态函数,而是Singleton singletonObj3=Singleton::GetInstance(),此句是调用复制构造函数,用GetInstance()返回的静态变量的值对singletonObj3对象初始化(此时在内存中有两个对象,静态对象和singletonObj3),为了防止此问题出现,应该也显示声明复制构造函数为私有。还有一个问题就是自我赋值,singletonObj1=singletonObj2,两者是同一个东西,为了防止此情况出现,我们可以在重载赋值操作中判断是否为同一个对象,但是单例模式中永远只有一个对象,那么我们干脆就显示声明赋值操作为私有既可。
即在类中把那两句注释消去,其实就是在编译中禁止了以上所说的两种操作,如果使用了,编译器会报错。
可以看出方法一、二、三都存在缺少delete的问题。
正常项目中,全局实例只有一个,在程序结束时,系统会释放内存资源,所以没有delete的问题并不大,不会发生内存泄露。但是在对象有 操作文件 或者 连接数据库 时,程序关闭时不会立即关闭资源,就需要在程序关闭前,手动释放资源。由于都是静态变量,因此不能使用类的析构函数对它进行销毁,有些人就想出了使用嵌套类专门处理释放资源。在方法一中加入嵌套类Garbo
class Singleton{private:Singleton():Data(0) //构造函数声明为私有{}static Singleton * Instance;public:static Singleton & GetInstance();int Data;//用于测试class Garbo //它的唯一工作就是在析构函数中删除CSingleton的实例{public:~Garbo(){if( Singleton::Instance )delete Singleton::Instance;}};static Garbo Garbo; //定义一个静态成员,程序结束时,系统会自动调用它的析构函数};Singleton * Singleton::Instance=NULL;Singleton & Singleton::GetInstance(){if(Instance == NULL) //判断是否实例已经存在{Instance = new Singleton();}return *Instance;}需要更详细的内容可以参考 果冻想 http://www.jellythink.com/archives/82
0 0
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 单例模式(单子模式)
- 设计模式-单例模式
- [设计模式] 单例模式
- 程序压力测试
- 15个顶级Java多线程面试题及回答
- Flash AS3 性能优化注意点
- Android 读取联系人2.0以上
- x264 - FENC_SRIDE、FDEC_STRIDE相关以及fenc、fdec的buf存储结构
- 单例模式
- 记WinCE下调试SIM900 GSM module
- Android Handler
- 关于setTimeout()用法的两种情形:
- CCDirector导演类
- 关于OE7.0中通过登录uid获取其部门的方法
- 一些常用的时间函数
- IE访问页面时自动切换到兼容模式的问题
- android edittext 去边框