zoukankan      html  css  js  c++  java
  • c++ 单例模式 对全局变量的替代

    前段时间要实习一个充值接口,创建了一个类(就叫类A好了),这个类A要和另外3个类进行交互,3个类对类A修改的数据是对其他类可见的。这种情况我想到了3个方法:

    1.static 静态成员,静态成员为该类的所有实例所共享,3个类中各自创建一个类A的对象,它们对静态成员的修改对其他类可见。

    2.全局变量,类A的头文件中添加   extern  classA  g_classA; 源文件中添加 classA g_classA;   3个类中添加头文件后直接通过g_classA   //这种不推荐

    3.单例模式

    使用单例模式替代全局变量,3个类对类A的函数访问都是对类A的唯一实例的数据访问,修改对其他类自然可见了。单例模式是使用全局变量的常见替代方法。

    下面是转自一位前辈的单例实现模式的总结,第三种实现实在太精彩了,只能用"nice catch"来形容!

    ——————————华丽的分割线——————————

    转自:http://lwzy-crack.blog.163.com/blog/static/9527204220091068526135/

    C++中的单例模式 

    单例模式很有用,使用单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
    但是在程序的开发过程中我们总是遇到一些问题,而这些问题主要集中在单例类的消毁过程中,普通使用的单例模式的类如下:
    class Singleton:
    {
        // 其它成员
    public:
        static Singleton * GetInstance()
        {
            if (m_pInstance == NULL)
                m_pInstance = new Singleton();
            return m_pInstance;
        }
     
    private:
        Singleton(){};
        static Singleton * m_pInstance;
    }

    可是这个类在什么时候调用它的析构函数呢,我们怎么消毁它。提供一个公用的destroy函数来进行它的消毁吗,这很不美观。最后我就在网上找到了如果下的代码处理了这个问题:
    class Singleton:
    {
        // 其它成员
    public:
        static Singleton * GetInstance(){...}
    private:
        Singleton(){};
        static Singleton * m_pInstance;
     
        class CGarbo // 它的唯一工作就是在析构函数中删除Singleton的实例
        {
        public:
            ~CGarbo(){
                if (Singleton::m_pInstance)
                    delete Singleton::m_pInstance;
            }
        };
     
        static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
    }

    这是非常好的方法,静态成员对象 Garbo 在析构时会自动的消毁单例,我们不用再担心这个问题了。

    但是添加一个类的静态对象,总是让人不太满意,所以有人用如下方法来重现实现单例和解决它相应的问题,代码如下:
    class Singleton:
    {
        // 其它成员
    public:
        static Singleton &GetInstance(){
            static Singleton instance;
            return instance;
        }
     
    private:
        Singleton(){};
    }
    使用局部静态变量,非常强大的方法,完全实现了单例的特性,而且代码量更少,也不用担心单例消毁的问题。
    在后期的项目中我全使用了这种方法,可是在项目的开发过程中还是出现了问题,当如下方法使用单例时问题来了,
    Singleton singletion = Singleto::GetInstance();
    这么做就产生了一个类拷贝的问题,这就为背了单例的特性。
    产生这个问题的原因在于,编译器会为类生成一个默认的构造函数,来支持类的拷贝。
    最后没有办法,我们要禁止类拷贝和类赋值,禁止程序员用这种方式来使用单例,当时领导的意思是GetInstance()函数返回一个指针而不是返回一个引用,函数代码改为如下:
        static Singleton *GetInstance(){
            static Singleton instance;
            return &instance;
        }

    可我总是感觉不好,为什么不让编译器不这么干呢。这时我才想起可以显式的声明类拷贝的构造函数,和重载=操作符,新的单例类如下:

    class Singleton:
    {
        // 其它成员
    public:
        static Singleton &GetInstance(){
            static Singleton instance;
            return instance;
        }
     
    private:
        Singleton(){};

        Singleton(const Singleton&);
        Singleton & operate = (const Singleton&);
    }
    关于Singleton(const Singleton&);和Singleton & operate = (const Singleton&);函数,我们要声明成私用的,并且只声明不实现。这样子后如果用上面的方式来使用单例时,不管是在友元类中还是其它的,编译器都是报错。
    不知道这样的单例类是否还会有问题,但在程序中这样子使用已经基本没有问题了。

    ——————————华丽的分割线——————————

  • 相关阅读:
    中国的信息产业一定由中国的工商业养活,中国的工商业一定要养活自己的信息产业
    2017-2018-1 20155201 《信息安全系统设计基础》第十三周学习总结
    2017-2018-1 20155201 实验五 通讯协议设计
    《深入理解计算机系统》第二章 信息的表示与处理
    2017-2018-1 20155201 《信息安全系统设计基础》第十一周学习总结
    2017-2018-1 20155201 实验四 外设驱动程序设计
    信息安全技术 实验四 木马及远程控制技术
    实验四
    2017-2018-1 20155201 《信息安全系统设计基础》第九周学习总结
    cmder使用手册
  • 原文地址:https://www.cnblogs.com/sixbeauty/p/3790693.html
Copyright © 2011-2022 走看看