单例模式

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式分为懒汉式饿汉式

懒汉式是当该实例第一次被引用时,才将自己实例化;
饿汉式是在被加载时就将自己实例化了。

懒汉式

class Singleton{
public:
    static Singleton* getInstance();
    void doSomething();
    void destroy();
    
private:
    Singleton();
    ~Singleton();
    Singleton(const Singleton&);
    Singleton& operator = (const Singleton&);
    static Singleton* instance;
};
Singleton* Singleton::instance = NULL;
Singleton::Singleton() {}
Singleton::~Singleton() {}
Singleton* Singleton::getInstance() {
    if(instance == NULL)
        instance = new Singleton();
    return instance;
}
void Singleton::destroy() {
    delete this;
    instance = NULL;
}
int main() {
    Singleton::getInstance()->doSomething();
    Singleton::getInstance()->destroy();
    return 0;
}

懒汉式是线程不安全的,当单例模式应用在多线程中,应该使用锁进行同步

class Singleton{
public:
    static Singleton* getInstance();
    void doSomething();
    void destroy();
    
private:
    Singleton();
    ~Singleton();
    Singleton(const Singleton&);
    Singleton& operator = (const Singleton&);
    static Singleton* instance;
};
Singleton* Singleton::instance = NULL;
Singleton::Singleton() {}
Singleton::~Singleton() {}
Singleton* Singleton::getInstance() {
    if(instance == NULL) {
        lock();
        if(instance == NULL)
            instance = new Singleton();
        unlock();
    return instance;
}
void Singleton::destroy() {
    delete this;
    instance = NULL;
}
int main() {
    Singleton::getInstance()->doSomething();
    Singleton::getInstance()->destroy();
    return 0;
}

而饿汉式是线程安全的

class Singleton{
public:
    static Singleton* getInstance();
    void doSomething();
    void destroy();
    
private:
    Singleton();
    ~Singleton();
    Singleton(const Singleton&);
    Singleton& operator = (const Singleton&);
    static Singleton* instance;
};
Singleton* Singleton::instance = new Singleton();
Singleton::Singleton() {}
Singleton::~Singleton() {}
Singleton* Singleton::getInstance() {
    return instance;
}
void Singleton::destroy() {
    delete this;
    instance = NULL;
}
int main() {
    Singleton::getInstance()->doSomething();
    Singleton::getInstance()->destroy();
    return 0;
}

优缺点

饿汉式
优点
1. 线程安全
2. 在类加载的同时已经创建好一个静态对象,调用时反应速度快
缺点
资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法,那么这个实例仍然初始化

懒汉式
优点:
避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。
缺点:
不是线程安全,在多线程中需要线程同步,同步加锁的过程提高了系统的开销

应用场景

  1. 网站的计数器,一般也是采用单例模式实现,否则难以同步。
  2. 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
  3. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
  4. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
  5. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
  6. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。

你可能感兴趣的:(单例模式)