美文网首页
单例模式(C++实现)

单例模式(C++实现)

作者: anycedo | 来源:发表于2019-08-20 13:29 被阅读0次

一、什么是单例模式

1.1单例模式的基本概念

    单例模式属于创建型模式,这种模式涉及到一种单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象的方式。
    单例类的特征:1.单例类最多只能有一个实例;2.单例类必须自己创建自己唯一的实例;3.单例类必须给所有其他的对象提供这一实例。

1.2使用单例模式的好处

    使用单例类是为了保证某一个类仅有一个实例,并提供一个访问它的全局访问点。
    单例类主要解决了一个全局使用的类的频繁的创建与销毁。
    所以单例模式有以下几个优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例;2、避免对资源的多重占用。
    那单例模式有一个不好的地方就是,单例类没有接口,不能继承。

1.3单例模式的使用场景

    当我们想在程序中控制实例数目,节约系统资源的时候,可以考虑使用单例类。
    >>1.Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。
    >>2.一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。

二、单例模式的C++实现

2.1懒汉式

    什么叫懒汉式的单例类呢?顾名思义,懒汉很懒,只有他饿了的时候才会去找吃的,也就是说只有在需要的时候才会去实例化。一次都没有需要的时候,不会去构造这个对象,这个程序中也就没有这个对象的实例,只有需要了一次了,实例化了一次,这个对象才会一直存在。

//Singleton.cpp
#include<iostream>
#include<mutex>
using namespace std;
//mutex singletonLock;
class Singleton {
public:
    static Singleton* getInstance() {
        static Singleton* singeltonInstance;//函数内的静态变量,声明加定义,已分配空间。
        cout << "getInstance in singleton." << endl;
//线程安全
        //if(singeltonInstance == NULL){
        //  singletonLock.lock();//线程安全
            if (singeltonInstance == NULL)
              singeltonInstance = new Singleton();
       //   singletonLock.unlock();
       //}
        return singeltonInstance;
    };
private:
    //static Singleton* singeltonInstance;//若在此处定义,类内的静态成员变量,要记得在类外部的cpp文件的全局进行初始化。(仅仅是声明,并没定义,所以没有分配空间)
//Static members obey the usual class member access rules (clause 11). When used in the declaration of a class member, the static specifier shall only be used in the member declarations that appear within the member-specification of the class declaration. [Note: it cannot be specified in memberdeclarations that appear in namespace scope. ] 
    Singleton() {
        cout << "Construct in singleton." << endl;
    }
    Singleton(const Singleton&);//拷贝构造函数和赋值运算符也是私有的,以禁止拷贝和赋值;
    Singleton& operator=(const Singleton&);
};

    
    懒汉式的单例类在多线程的使用中存在线程安全问题。如果有两个线程同时获取单例类的实例,又都发现实例不存在,因此都会进行实例化,会产生两个实例都要赋给singeltonInstance,会造成严重的错误,要解决这个问题就要加锁。上面程序注释掉的为线程安全的部分,即为懒汉式单例模式线程安全问题的一个解决方案。

2.2饿汉式

    饿汉式的单例类,会在全局作用域进行单例类的实例化,并以此来初始化。

//Singleton.cpp
#include<iostream>
using namespace std;
class Singleton;
class Singleton {
private:
    Singleton() {};//构造函数私有化
    Singleton(Singleton &s) {}; //拷贝构造私有化
    Singleton& operator=(const Singleton& s) {};
    static Singleton* singletonInstance;
public:
    static Singleton* getInstance() {
        return singletonInstance;
    }
};
//......
Singleton* Singleton::singletonInstance = new Singleton();//全局实例化

2.3 单例模式的GC

    1.单例模式中实例化的对象是new出来的,需要对它负责,也就是需要delete;
    2.delete一个对象时,会调用它的析构函数;
    3.如果在析构函数里使用delete进行内存管理,由于对象是new出来的,根本进不去析构函数,无法自动的销毁;
    4.如果在析构函数里使用delete进行内存管理,就一定会造成一个析构的循环的(见2)。

    那么应该怎样在C++的程序中显式的进行单例对象的内存管理呢?一个比较好的方法是定义一个内部垃圾回收类,并且在Singleton中定义一个此类的静态成员。程序结束时,系统会自动析构此静态成员,此时,在此类的析构函数中析构Singleton实例,就可以实现singletonInstance的自动释放。

//Singleton.cpp
#include<iostream>
using namespace std;
class Singleton;
class Singleton {
private:
    Singleton() { cout << "Construct singleton." << endl; };//构造函数私有化
    Singleton(Singleton &s) {}; //拷贝构造私有化
    Singleton& operator=(const Singleton& s) {};
    static Singleton* singletonInstance;

    class SingletonCG {//单例的回收
    public:
        ~SingletonCG(){
            if (singletonInstance != NULL)
                delete singletonInstance;
            singletonInstance = NULL;
            cout << "Singleton delete." << endl;
            system("pause");
        }
    };
    static SingletonCG cg;
public:
    static Singleton* getInstance() {
        cout << "getInstance." << endl;
        return singletonInstance;
    }
    
};
//......
Singleton* Singleton::singletonInstance = new Singleton();//全局实例化
Singleton::SingletonCG Singleton::cg;////类的静态成员需要类外部初始化,这一点很重要,否则程序运行连GC的构造都不会进入,何谈自动析构

三、使用单例模式的注意事项

四、参考资料

[1]单例模式——菜鸟教程
[2]单例模式——C++实现
[3]单例模式——C++的GC

相关文章

  • 单例模式

    单例模式及C++实现代码单例模式4种实现详解 c++11改进我们的模式之改进单例模式 单例模式(Singleton...

  • 学而时习之单例模式

    本文主要说明单例模式的概念,应用,以及C++实现。 I、上帝视角看单例模式 1.1 单例模式特点 单例模式需要满足...

  • Singleton 单例模式

    搬运自大神博客单例模式(Singleton)及其C++实现 单例模式,在GOF的《设计模式:可复用面向对象软件的基...

  • C++ 单例模式

    本文介绍C++单例模式的集中实现方式,以及利弊 局部静态变量方式 上述代码通过局部静态成员single实现单例类,...

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • python面试题-2018.1.30

    问题:如何实现单例模式? 通过new方法来实现单例模式。 变体: 通过装饰器来实现单例模式 通过元类来创建单例模式...

  • 单例模式

    一、实现单例模式 或者 二、透明的单例模式 三、用代理实现单例模式 四、JavaScript中的单例模式 在Jav...

  • 单例模式和GCD单例实现

    1、传统单例模式2、GCD单例模式3、用宏实现GCD单例模式4、用宏实现GCD单例模式,名称随类名变化而变化 单例...

  • kotlin实现单例模式

    1.懒汉式实现单例模式 2.线程安全懒汉式实现单例模式 3.双重校验懒汉式实现单例模式 4.静态内部类方式实现单例模式

  • 单例模式之枚举类enum

    通过枚举实现单例模式 枚举类实现单例模式的优点 对于饿汉式单例模式和懒汉式单例模式了解的同学,使用以上两种单例模式...

网友评论

      本文标题:单例模式(C++实现)

      本文链接:https://www.haomeiwen.com/subject/tekusctx.html