单例模式是应用最多的一种设计模式,它要求系统中每个类有且只能有一个实例对象。

主要优点:

1、提供了对唯一实例的受控访问。

2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。

3、允许可变数目的实例。

主要缺点:

1、由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。

2、单例类的职责过重,在一定程度上违背了“单一职责原则”。

3、滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。

C++设计一个单例模式的方法如下:

1 构造函数声明为私有;   这样就保证了不能随意构造一个对象

2 将拷贝构造函数与等号运算符声明为私有,并不提供他们的实现; 即禁止对象被拷贝。

3 在类中声明一个静态的全局访问接口;

4 声明一个静态的私有实例化指针;

  1. class Singleton
  2. {
  3. public:
  4. //全局访问接口
  5. static Singleton *GetInstance()
  6. {
  7. if( instance_ == NULL )
  8. {
  9. instance_ = new Singleton;
  10. }
  11. return instance_;
  12. }
  13. ~Singleton()
  14. {
  15. cout << "~Singleton"<< endl;
  16. }
  17. private:
  18. Singleton(const Singleton& other);
  19. Singleton & operator=(const Singleton & other);
  20. Singleton()
  21. {
  22. cout << "Singleton"<<endl;
  23. }
  24. static Singleton *instance_; //引用性声明
  25. };
  26. Singleton * Singleton::instance_; //定义性声明
  27. int main(void)
  28. {
  29. Singleton *s1 = Singleton::GetInstance();
  30. Singleton *s2 = Singleton::GetInstance();  //s2的地址等于s1,即指向同一对象
  31. //Singleton s3(*s1); //既然是单例模式,是不允许被拷贝的。编译会出错
  32. return 0;
  33. }

上面就是单例类模式的C++实现,但是上述代码还有一个缺陷:单例类中申请的一些资源没有被释放,如instance_指向的空间没有被回收。一共有两种解决方式:

第一种解决方式:

  1. class Singleton
  2. {
  3. ...
  4. //提供一个回收接口,在应用中显示调用回收资源
  5. static void Free()
  6. {
  7. delete instance_;
  8. }
  9. ....
  10. };
  11. int main()
  12. {
  13. ...
  14. Singleton::Free(); //要显示调用进行资源回收
  15. }

这种方式虽然能实现功能,但是不太方便,每次都要手动回收资源,这是它的缺点。

第二种解决方式:

  1. class Singleton
  2. {
  3. ...
  4. public:
  5. class Garbo //资源回收机制
  6. {
  7. public:
  8. ~Garbo()
  9. {
  10. if( Singleton::instance_ != NULL )
  11. {
  12. delete instance_;
  13. }
  14. }
  15. };
  16. ...
  17. private:
  18. ...
  19. static Garbo garbo_;  //引用性声明
  20. };
  21. Singleton::Garbo Singleton::garbo_;//定义性声明

这种方式提供的处理方式显然要比第一种方式来的要便捷,因为它依靠内部提供的Garbo嵌套类来提供服务,当Singleton类生命周期结束时,Garbo的类对象garbo_也要销毁,它将调用析构函数,而在析构函数中又自动地释放了Singleton单例类申请的一些资源,这种实现就比较智能化。不需要手动释放资源。这是它的优势。

下面提供另一种实现C++单例类模式的方法:

  1. class Singleton
  2. {
  3. public:
  4. static Singleton& GetInstance()
  5. {
  6. static Singleton instance_;                   return instance_;
  7. }
  8. ~Singleton()
  9. {
  10. cout << "~Singleton"<<endl;
  11. }
  12. private:
  13. Singleton()
  14. {
  15. cout << "Singleton "<<endl;
  16. }
  17. Singleton(const Singleton &other);
  18. Singleton & operator=(const Singleton &other);
  19. };

这种实现方式利用了static修改函数内部的变量,当第一次调用GetInstance函数时,系统将构造一个Singleton对象,在后续再次调用这个函数时,系统不再执行这个语句,也就不会再构造Singleton类对象了,而直接返回instance_本身。另外,当Singleton类对象生命周期结束时,对象会自动调用析构函数销毁,这里也就不存在申请资源之类的了,需要注意的是GetInstance()函数返回的是引用,这样就不会调用拷贝构造函数了,使用时也应该声明Singleton的引用,如下:

  1. int main()
  2. {
  3. Singleton &s1 = Singleton::GetInstance();
  4. Singleton &s2 = Singleton::GetInstance(); //s1与s2是同一对象的引用
  5. return 0;
  6. }

C++ static与单例模式的更多相关文章

  1. C# 的static与单例模式

    C# 的static与单例模式 static是静态对象,在类被第一次使用,或者第一次被实例化时执行 /// <summary> /// 线程安全的单件模式 /// </summary ...

  2. static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符

    一.static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝  C++ Code  1 2 3 4 5 6 7 8 9 10 11 ...

  3. (1) 类构造块,this(),static,单例模式串讲

    类构造块 在类只用一对大括号包含的内容,构造所有的对象时都会执行的内容,如果某个类有好几个够赞函数,公共部分抽取出来,放到构造块中. clas Boy { ... { syso("哭...& ...

  4. 第六节 静态的(static)和单例模式

    main函数 主函数是一个特殊的函数,作为程序的入口,可以被jvm(虚拟器)调用 主函数的定义 public 表示该函数的访问权限是最大的. static 代表主函数随着类的加载就已经存在了. voi ...

  5. 单例模式(一)static、final和单例模式

    static 那天我朋友问了我个问题,static和单例模式有什么区别,所以我觉得static可以讲一下 他的问题是,把对象弄成static是不是就不变了 显然,这是还没弄清楚引用和对象的区别 其实存 ...

  6. java中static关键字的作用

    java中static关键字主要有两种作用: 第一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关. 第二,实现某个方法或属性与类而不是对象关联在一起 简单来说,在Java语言中,s ...

  7. 【设计模式】单例设计模式的N中Java实现方法

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17359719 特点 单例模式的特点: 1.只能有一个实例: 2.必须自己创建自己的一个实例 ...

  8. 探测器 C++ Singleton(辛格尔顿)

    一.静态模式不是单一的情况下, 刚开始学习的人可能误, 误以为所有的成员变量和成员方法用于 static , 就是单例模式了: class Singleton { public:     /* sta ...

  9. java开发常用技术

    基础部分 1. 线程和进程的区别 线程三个基本状态:就绪.执行.阻塞 线程五个基本操作:创建.就绪.运行.阻塞.终止 进程四种形式:主从式.会话式.消息或邮箱机制.共享存储区方式 进程是具有一定功能的 ...

随机推荐

  1. VS2010下C/C++连接MySql数据库的方法

    1. 新建一个C++控制台程序 2. 选择项目 CMySql属性 3. 选择配置属性 C/C++ 常规 附加包含目录 4. 添加包含目录C:\Program Files\MySQL\Connector ...

  2. start running 开始跑步减肥

    begin 两个月前,逛超市的时候站在体重秤上称了称,一直以为自己体重很正常(BMI<25,虽然也不轻~~~),结果直接迈过超重,奔着肥胖跑去了(BMI>30,BMI计算器 http:// ...

  3. [置顶] 学习JDK源码:编程习惯和设计模式

    编程习惯 1.用工厂方法替代构造函数 Boolean.valueOf() 通过一个boolean简单类型,构造Boolean对象引用. 优点:无需每次被调用时都创建一个新对象.同时使得类可以严格控制在 ...

  4. Hibernate之AbstractEntityPersister

    Hibernate开发中需要根据持久层对象获取所映射的数据库表相关信息,如表名,主键,外键对象等相关系. Hibernate配置 Hibernate.cfg.xml <?xml version= ...

  5. C++中的引用和移动语义

    C++引用现在分为左值引用和右值引用.其实很好理解,左值引用中的左值指的就是能出现在等号左边的值(带名称的变量,带*号的指针等一类的数据),程序能对这样的左值进行引用获得其地址:右值引用中的右值指的就 ...

  6. Power BI移动端应用

    随笔- 420  文章- 6  评论- 1927  无处不在的商业智能---Power BI移动端应用   此篇来自于微软商业智能网站的官方博客团队发布的Power BI在线资料其中的一部分,完整版地 ...

  7. Python Redis 数据复制.

    1 > 下载Python操作Redis的客户端 https://pypi.python.org/pypi/redis/2.7.6 下载完成后,参考该网站相关命令,执行安装. 2 > 下载 ...

  8. ios学习笔记(二)之Objective-C类、继承、类别和协议

    二:Objective-C类与继承和协议 在前面已经提过了对象的初始化,这里首先讲的是变量. 2.1 变量 局部变量(内部变量): 局部变量是在方法内作定义说明的,其作用域仅限于方法内,离开方法后使用 ...

  9. linux下面安装配置mongoDB

    不知道为什么官网最新的2.4我一直解压失败 下载之前确认一下你的操作系统是64位的还是32位的对应去下载 64位链接:http://fastdl.mongodb.org/linux/mongodb-l ...

  10. 代码契约CodeContract(八)

    代码契约(Code Contract):它并不是语言本身的新功能,而是一些额外的工具,帮助人们控制代码边界. 代码契约之于C#,就相当于诗词歌赋之于语言. --- C# in Depth 一,概述 1 ...