[设计模式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() 时被构造,一直保持活动状态直到应用程序终止.

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

原文地址:https://www.cnblogs.com/hustcser/p/4157572.html