zoukankan      html  css  js  c++  java
  • [设计模式1]--单例模式(SINGLETON)

    搞笑解释:

        俺有6个漂亮的老婆,她们的老公都是我,我就是我们家里的老公Sigleton,她们只要说道“老公”,都是指的同一个人,那就是我 

    定义:

        单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。 

    人话:

        保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。(你就是个全局变量的程度啊)

    于是,可以写出以下的事例:

    class Singleton {
    public:
        static Singleton* Object(){   //公有的静态方法,来获取该实例  
            if (pIn == NULL)
                pIn = new Singleton();
            return pIn;
        }
    private:
        Singleton(){};               //私有构造函数,防止实例化
        static Singleton* pIn;       //私有静态指针变量,指向类的唯一实例
    };

    接下来我们可以测试一下这个类是否只有一个实例。

    Singleton* Singleton::pIn = NULL;   // 这一行必须声明,不然编译不通过,原因可以参考我的博客<static成员>
    
    int main() {
        Singleton* pS1 = Singleton::Object();
        Singleton* pS2 = Singleton::Object();
        Singleton* pS3 = pS1->Object();
        Singleton &pS4 = * Singleton::Object();
    
        if (pS1 == pS2) 
            cout << "pS1 == pS2" << endl;
        if (pS1 == pS3)
            cout << "pS1 == pS3" << endl;
        if (pS1 == &pS4)
            cout << "pS1 == &pS4" << endl;
    
        system("pause");
    }

    结果输出:

    pS1 == pS2
    pS1 == pS3
    pS1 == &pS4

    可以得知:得到的全是一个实例!

    另外,从测试函数中我们可以发现单例类有以下的性质:

    1.它有一个指向唯一实例的静态指针pIn,并且是私有的;

    2.它有一个公有的函数,可以获取这个唯一的实例,并且在需要的时候创建该实例;

    3.它的构造函数是私有的,这样就不能从别处创建该类的实例。

    上面的单例类中,我们new了一个实例,但是却没有释放它,可能你想会有这么几种方法来解决:

    1.在程序结束时调用 GetInstance(),并对返回的指针掉用 delete操作。这样做可以实现功能,但不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用 GetInstance 函数。也就是说释放操作由使用者来管理,而不是由类本身来管理,这违背了类的单一职责的原则,这是不合理的。

    2.用析构函数?

      很遗憾,就算我们声明了析构函数,还是不能释放,因为我们的实例是new出来的,所以只有 delete 时,才会调用析构函数,但是在哪里调用 delete 呢!

    3.用静态局部变量来解决:

    class Singleton {
    public:
        static Singleton* Object(){
            static Singleton pIn;   //静态局部变量
            return &pIn;
        }
    private:
        Singleton(){};
    };

    局部静态对象实例 instance 是第一次调用 GetInstance() 时被构造,一直保持活动状态直到应用程序终止.

    与动态分配对象不同,静态对象当应用程序终止时被自动销毁掉,所以就不必再手动销毁实例了。

  • 相关阅读:
    docker容器,镜像常用操作
    微信小程序登录状态
    微信小程序登录流程图
    GET和POST可传递的值到底有多大?
    php发送请求
    thinkphp 导入微信小程序加密解密库
    thinkphp 随机获取一条数据
    bootstrap row 行间距
    webstorm es6 语法报错
    Laravel
  • 原文地址:https://www.cnblogs.com/hustcser/p/4157572.html
Copyright © 2011-2022 走看看