设计模式

单例模式

确保一个类只有一个实例,并提供该实例的全局访问点。

设计模式_第1张图片

实现:

单例模式有两种实现方法:分别是懒汉和饿汉模式。

  • 懒汉模式,即非常懒,不用的时候不去初始化,所以在第一次被使用时才进行初始化;

只有在真正使用的时候才会实例化一个对象并交给自己的引用

  • 饿汉模式,即迫不及待,在程序运行时立即初始化。例模式(饿汉模式和懒汉模式),线程安全版本

实现:私有化它的构造函数,以防止外界创建单例类的对象;使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。

应用场景:

  • 1.需要生成唯一序列的环境
  • 2.需要频繁实例化然后销毁的对象。
  • 3.创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
  • 4.方便资源相互通信的环境

优点与缺点

优点:

  • 在内存中只有一个对象,节省内存空间
  • 避免频繁的创建销毁对象,可以提高性能
  • 避免对共享资源的多重占用,简化访问
  • 为整个系统提供一个全局访问点

缺点:

  • 不适用于变化频繁的对象
  • 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出
  • 如果实例化的对象长时间不被利用,系统会认为该对象是垃圾而被回收,这可能会导致对象状态的丢失

懒汉模式与饿汉模式

  • 懒汉模式:在getinstance中实例化

  • 饿汉模式:在单例类定义时实例化

懒汉模式

  • 懒汉式-线程不安全
class single{
private:
	static single *p;
	single(){}
	~single(){}

public:
	static single* getinstance();
};

single* single::p = NULL;
single* single::getinstance(){
	if (NULL == p)
		p = new single;

	return p;
}
  • 懒汉式-双检测锁线程安全
//懒汉模式线程安全内部静态变量实现
//将经典实现中的私有唯一实例删掉
//改为在instance函数里定义一个静态的实例
//也可以保证拥有唯一实例,在返回时只需要返回其指针就可以
class single{
private:
	static single *p;
	static pthread_mutex_t lock;
	single(){
		pthread_mutex_init(&lock, NULL);
	}
	~single(){}

public:
    //公有静态方法获取实例
	static single* getinstance();

};
pthread_mutex_t single::lock;
single* single::p = NULL;
single* single::getinstance(){
	if (NULL == p){
		pthread_mutex_lock(&lock);
		if (NULL == p)
			p = new single;
	}
	pthread_mutex_unlock(&lock);
	return p;
}
  • 局部静态变量之线程安全懒汉模式
//C++11后安全,不需要加锁

//懒汉模式线程安全内部静态变量实现
//将经典实现中的私有唯一实例删掉
//改为在instance函数里定义一个静态的实例
//也可以保证拥有唯一实例,在返回时只需要返回其指针就可以
 class single{
 private:
     single(){}
     ~single(){}
 
 public:
     static single* getinstance();
 
 };

single* single::getinstance(){
    static single obj;
    return &obj;
}

饿汉模式

饿汉模式不需要用锁,就可以实现线程安全。原因在于,在程序运行时就定义了对象,并对其初始化。之后,不管哪个线程调用成员函数getinstance(),都只不过是返回一个对象的指针而已。线程安全的,不需要在获取实例的成员函数中加锁

/*饿汉模式不需要用锁,就可以实现线程安全。原因在于,在定义单例类最初就实例化,此后返回的就一个,感觉相当于全局变量。之后,不管哪个线程调用成员函数getinstance(),都只不过是返回一个对象的指针而已
线程安全的,不需要在获取实例的成员函数中加锁。*/
class single{
private:
	static single* p;
	single(){}
	~single(){}

public:
	static single* getinstance();

};
single* single::p = new single();
single* single::getinstance(){
	return p;
}

int main(){

	single *p1 = single::getinstance();
	single *p2 = single::getinstance();

	if (p1 == p2)
		cout << "same" << endl;

	system("pause");
	return 0;
}

C++嵌套类在单例模式Singleton中自动释放堆内存的应用

#ifndef SINGLETON_H
#define SINGLETON_H
#include 
#include 

class SingleTon
{
public:
    static SingleTon * getInstance();
    void doSomething() {
        std::cout << "Do Something!" << std::endl;
    }
    ~SingleTon() { }
private:
    SingleTon() { }
    static SingleTon * instance;
    static std::mutex m_mutex;

    class GC //这是一个嵌套类
    {
    public:
        ~GC() {
            //可以在这里销毁所有的资源
            if(instance != nullptr) {
                std::cout << "Here destroy the instance of SingleTon!" << std::endl;
                delete instance;
                instance = nullptr;
            }
        }
        static GC gc; //用于释放堆内存中创建的单例对象
    };
};

#endif // SINGLETON_H

你可能感兴趣的:(复习笔记)