C++: 单例模式和缺陷

实现一个单例模式

1 class Singleton {
2     private:
3         Singleton() { cout << "Singleton::constructor" << endl; }
4         ~Singlton() { cout << "Singleton::destructor" << endl; }
5         Singleton(const Singleton&) {};
6         Singleton &operator=(const Singleton&) {};
7     public:
8         static Singleton* getInstance() {
9             if(m_aInstance == NULL) {
10                 m_aInstance = new Singleton();
11             }
12             return m_aInstance;
13         }
14         void show() {
15             cout << "Singleton::show" << endl;
16         }
17     private:
18         static Singleton* m_aInstance;
19 };
20  
21 Singleton* Singleton::m_aInstance = NULL;
22  
23 int main(int argc, char **argv) {
24     Singleton* aSingleton = Singleton::getInstance();
25     aSingleton->show();
26     return 0;
27 }
编译执行上面的代码,输出如下:

Singleton::constructor
Singleton::show
我们发现上面的输出并没有调用到Singleton的虚构函数,Singleton的资源可能没有被释放。现在的问题是要怎么才能在程序退出的时候正确释放Singleton的资源。我们注意到这样一个事实:

系统会自动调用在栈和静态数据区上分配的对象的析构函数来释放资源。

修改程序如下:

1 class Singleton {
2     private:
3         Singleton() { cout << "Singleton::constructor" << endl; }
4         ~Singleton() { cout << "Singleton::destructor" << endl; }
5         Singleton(const Singleton&) {};
6         Singleton &operator=(const Singleton&) {};
7     public:
8         static Singleton* getInstance() {
9             if(m_aInstance == NULL) {
10                 m_aInstance = new Singleton();
11             }
12             return m_aInstance;
13         }
14         void show() {
15             cout << "Singleton::show" << endl;
16         }
17  
18     private:
19         class Garbage{
20             public:
21                 ~Garbage() {
22                     if(m_aInstance != NULL) {
23                         delete m_aInstance;
24                     }
25                 }
26         };
27      
28     private:
29         static Singleton* m_aInstance;
30         static Garbage m_garbage;
31 };
32  
33 Singleton* Singleton::m_aInstance = NULL;
34 Singleton::Garbage Singleton::m_garbage;
35  
36 int main(int argc, char **argv) {
37     Singleton* aSingleton = Singleton::getInstance();
38     aSingleton->show();
39     return 0;
40 }
编译上面的代码并执行,输出如下:

Singleton::constructor
Singleton::show
Singleton::destructor

我们看到Singleton::destructor被明确的执行了。

C++: 单例模式和缺陷的更多相关文章

  1. DCL单例模式中的缺陷及单例模式的其他实现

    DCL:Double Check Lock ,意为双重检查锁.在单例模式中懒汉式中可以使用DCL来保证程序执行的效率. 1 public class SingletonDemo { 2 private ...

  2. GJM : C#设计模式(1)——单例模式

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  3. C#设计模式(1)——单例模式

    一.概念:确保一个类只有一个实例,并提供一个全局访问点. 二.单例模式具备如下几个特点: 1.只有一个实例. 2.能够自我实例化. 3.提供全局访问点.  三.代码实现 1.简单实现 /// < ...

  4. 【白话设计模式四】单例模式(Singleton)

    转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...

  5. 设计模式(一)单例模式(Singleton Pattern)

    一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设计模式>,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了 ...

  6. ios 开发之单例模式

    在iOS开发中,有很多地方都选择使用单例模式.有很多时候必须要创建一个对象,并且不能创建多个,用单例就为了防止创建多个对象.单例模式的意思就是某一个类有且只有一个实例.单例模式确保某一个类只有一个实例 ...

  7. 解决 PhpStorm 对 用单例模式实例化PHP类时,代码自动提示功能失效 的问题

    大部分PHP框架中,为了防止一个类被重复实例化,往往采用“单例模式”实例化类.我们的项目框架是这样做的: 先写好一个基类 /framework/Base.class.php,内容如下: <?ph ...

  8. Java提高篇——单例模式

    介绍 在我们日常的工作中经常需要在应用程序中保持一个唯一的实例,如:IO处理,数据库操作等,由于这些对象都要占用重要的系统资源,所以我们必须限制这些实例的创建或始终使用一个公用的实例,这就是我们今天要 ...

  9. 《JAVA与模式》之单例模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述单例模式的: 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式的 ...

随机推荐

  1. ifndef/define/endif作用和用法

    问题:ifndef/define/endif”主要目的是防止头文件的重复包含和编译,偶只知道这个概念不懂的是怎么个用法,和为什么要用它~~高手请指点一下~~谢谢~~~!!! ------------- ...

  2. 剑指offer——替换字符串

    总结:先计算出总共有多少空格,count++:然后从后往前遍历,每遇到一个空格,count--:       替换空格 参与人数:2119时间限制:1秒空间限制:32768K 通过比例:20.23% ...

  3. UIProgressView[进度条][一般型];UIStepper步数器][事件驱动型]

    ////  ViewController.m//  ProgressAndSteper////  Created by hehe on 15/9/21.//  Copyright (c) 2015年 ...

  4. Linux小白最佳实践:《超容易的Linux系统管理入门书》(连载五)Linux系统的对话方式

    本篇是Linux小白最佳实践第5篇,目的就是让白菜们了解Linux进程之间是如何对话的.之前连载的几篇,在微信上引起了很多的反响,有人也反映图多文字少,感觉没有干货.本篇选了大部分是实战讲解的&quo ...

  5. windows下redis 开机自启动

    1,在redis的目录下执行(执行后就作为windows服务了) redis-server --service-install redis.windows.conf 2,安装好后需要手动启动redis ...

  6. [java学习笔记]java语言核心----面向对象基础

    1.面向对象概述 面向对象是java语言的核心.是对应于面向过程而言的. 面向过程:强调的是过程,即动作.在java中动作就是函数.C语言就是面向过程的. 如:把大象装进冰箱需要几步? 答:需要三步: ...

  7. 在Centos6.5安装MySQL

    在阐述安装过程之前一定要再写一句,Centos7上安装MySQL是默认安装的MariaDB,因为在Centos7中用MariaDB代替了mysql数据库. linux安装软件很简单,有的时候只有一句话 ...

  8. js分割文件快速上传

    <?php header('Content-type:text/html;charset=UTF-8'); ?> <?php if ($_FILES) { if(!file_exis ...

  9. PHP中使用多线程

    <?php while(1)//循环采用3个进程 { //declare(ticks=1); $bWaitFlag= FALSE; // 是否等待进程结束 //$bWaitFlag = TRUE ...

  10. 【Vmware】已有镜像文件的导入

    1  虚拟机文件夹中各个文件简介 在创建虚拟机的时候会把相关的文件保存到一个文件夹中.我的机器是Windows 7,64位 ,保存的路径是: C:\Users\User\Documents\Virtu ...