C++ 中的单例模式(普通,2B,文艺)

一、普通Singleton

代码如下:

#include<iostream>
using namespace std;
class Singleton
{
    public:
        static Singleton* getInstance();
    private:
        static Singleton* instance;
        Singleton()
        {
            cout<<"constructor\n";
            // do something
        };
        ~Singleton()
        {
            cout<<"destructor\n";
            //do something
        }
};
Singleton* Singleton::instance = NULL;
Singleton* Singleton::getInstance()
{
    if(instance == NULL)
        instance = new Singleton();
    return instance;
}
int main()
{
    cout<<"begin main\n";
    Singleton* instance = Singleton::getInstance();
    cout<<"end main\n";
}

但是这样构造函数不会自动调用,需要用户这个类的用户手动delete instance. 这样是不太好的

这是懒汉式的,在多线程的情况下需要同步。也可以写成饿汉式的,但是c++里面写成饿汉式的不太好,如果有多个单例类,而他们是相互引用的,那么饿汉式就有可能出问题。因为在C++中,这几个单例类的静态成员的初始化顺序是不确定的。

二、2B的Singleton

代码如下:

#include<iostream>
using namespace std;
class Singleton
{
    public:
        static Singleton* getInstance();
    private:
        static Singleton* instance;
        Singleton()
        {
            cout<<"constructor\n";
            // do something
        };
        ~Singleton()
        {
            cout<<"destructor\n";
            //do something
        }
        class Garbo
        {
            public:
                ~Garbo()
                {
                    cout<<"Garbo destructor\n";
                    if(Singleton::instance != NULL)
                        delete Singleton::instance;
                }
        };
        static Garbo garbo;
};
Singleton* Singleton::instance = NULL;
Singleton::Garbo Singleton::garbo;
Singleton* Singleton::getInstance()
{
    if(instance == NULL)
        instance = new Singleton();
    return instance;
}
int main()
{
    cout<<"begin main\n";
    Singleton* instance = Singleton::getInstance();
    cout<<"end main\n";
}

用了一个内部类, Garbo。 由于main结束后,会自动释放 garbo, 而garbo就会调用instance的destructor.

三、文艺Singleton

代码如下:

#include<iostream>
using namespace std;
class Singleton
{
    public:
        static Singleton* getInstance();
    private:
        static Singleton instance;
        Singleton()
        {
            cout<<"constructor\n";
            // do something
        };
        ~Singleton()
        {
            cout<<"destructor\n";
            //do something
        }
};
Singleton Singleton::instance;
Singleton* Singleton::getInstance()
{
    return &instance;
}
int main()
{
    cout<<"begin main\n";
    Singleton* instance = Singleton::getInstance();
    cout<<"end main\n";
}

instance在main开始前就已经构造好了,在main结束后会自动释放。

但是这样的话,只能是饿汉式的singleton。如果在构造函数中需要申请大量资源,这些资源就一直存在在整个运行阶段。而不管这些资源什么时候需要,什么时候不许要。

四、改进的文艺Singleton

代码如下:

#include<iostream>
using namespace std;
class Singleton
{
    public:
        static Singleton* getInstance();
    private:
        Singleton()
        {
            cout<<"constructor\n";
            // do something
        };
        ~Singleton()
        {
            cout<<"destructor\n";
            //do something
        }
};
Singleton* Singleton::getInstance()
{
    static Singleton instance;
    return &instance;
}
int main()
{
    cout<<"begin main\n";
    Singleton* instance = Singleton::getInstance();
    cout<<"end main\n";
}

这样,就可以在需要的时候再构造singleton, 也就是懒汉式的。

(0)

相关推荐

  • 从C++单例模式到线程安全详解

    先看一个最简单的教科书式单例模式: class CSingleton { public: static CSingleton* getInstance() { if (NULL == ps) {//tag1 ps = new CSingleton; } return ps; } private: CSingleton(){} CSingleton & operator=(const CSingleton &s); static CSingleton* ps; }; CSingleton*

  • 老生常谈C++的单例模式与线程安全单例模式(懒汉/饿汉)

    1 教科书里的单例模式 我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例. 上代码: class singleton { protected: singleton(){} private: static singleton* p; public: static singleton* instance()

  • 使用设计模式中的单例模式来实现C++的boost库

    线程安全的单例模式 一.懒汉模式:即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例. 需要用锁,来保证其线程安全性:原因:多个线程可能进入判断是否已经存在实例的if语句,从而non thread safety. 使用double-check来保证thread safety.但是如果处理大量数据时,该锁才成为严重的性能瓶颈. 1.静态成员实例的懒汉模式: class Singleton { private: static Singleton* m_instance; Sing

  • C++中的单例模式介绍

    有很多地方需要这样的功能模块,如系统的日志输出,GUI应用必须是单鼠标,MODEM的联接需要一条且只需要一条电话线,操作系统只能有一个窗口管理器,一台PC连一个键盘. 单例模式有许多种实现方法,在C++中,甚至可以直接用一个全局变量做到这一点,但这样的代码显的很不优雅. 使用全局对象能够保证方便地访问实例,但是不能保证只声明一个对象--也就是说除了一个全局实例外,仍然能创建相同类的本地实例. <设计模式>一书中给出了一种很不错的实现,定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并

  • C++单例模式的实例详解

    单例模式概述 个人认为单例模式是设计模式中最为简单.最为常见.最容易实现,也是最应该熟悉和掌握的模式.且不说公司企业在招聘的时候为了考察员工对设计的了解和把握,考的最多的就是单例模式. 单例模式解决问题十分常见,我们怎样去创建一个唯一的变量(对象)?在基于对象的设计中我们可以通过创建一个全局变量(对象)来实现,在面向对象和面向过程结合的设计范式(如 C++中)中,我们也还是可以通过一个全局变量实现这一点.但是当我们遇到了纯粹的面向对象范式中,这一点可能就只能是通过单例模式来实现了,可能这也正是很

  • C++单例模式应用实例

    本文实例讲述了C++单例模式及其相关应用方法,分享给大家供大家参考.具体方法分析如下: 定义: 一个类有且仅有一个实例,并且提供一个访问它的全局访问点. 要点: 1.类只能有一个实例: 2.必须自行创建此实例: 3.必须自行向整个系统提供此实例. 实现一:单例模式结构代码 singleton.h文件代码如下: #ifndef _SINGLETON_H_ #define _SINGLETON_H_ class Singleton { public: static Singleton* GetIns

  • C++设计模式之单例模式

    问题描述 现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能:在实际开发过程中,会专门有一个日志模块,负责写日志,由于在系统的任何地方,我们都有可能要调用日志模块中的函数,进行写日志.那么,如何构造一个日志模块的实例呢?难道,每次new一个日志模块实例,写完日志,再delete,不要告诉我你是这么干的.在C++中,可以构造一个日志模块的全局变量,那么在任何地方就都可以用了,是的,不错.但是,我所在的开发部门的C++编码规范是参照Google的编码规范的. 全局变量在项目

  • C++ 单例模式的详解及实例

    C++ 单例模式的详解及实例 1.什么叫单例模式? 单例模式也称为单件模式.单子模式,可能是使用最广泛的设计模式.其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享.有很多地方需要这样的功能模块,如系统的日志输出,GUI应用必须是单鼠标,MODEM的联接需要一条且只需要一条电话线,操作系统只能有一个窗口管理器,一台PC连一个键盘. 通过单例模式, 可以做到: (1)确保一个类只有一个实例被建立 (2)提供了一个对对象的全局访问指针 (3)在不影响单例类的客户端

  • C++和java设计模式之单例模式

    单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点.其构造过程由自身完成,可以将构造方法定义为private型的,这样外界就只能通过定义的静态的函数Instance()构造实例,这个函数的目的就是返回一个类的实例,在此方法中去做是否有实例化的判断.客户端不再考虑是否需要去实例化的问题,把这些都交给了单例类自身.通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象.一个最好的办法,就是让类自身负责保存它的唯一实例.这个类可以保证没有其他实例可

  • C++实现 单例模式实例详解

    设计模式之单例模式C++实现 一.经典实现(非线程安全) class Singleton { public: static Singleton* getInstance(); protected: Singleton(){} private: static Singleton *p; }; Singleton* Singleton::p = NULL; Singleton* Singleton::getInstance() { if (NULL == p) p = new Singleton()

随机推荐