设计模式——单例模式

设计模式——单例模式,第1张

一、class="superseo">单例模式的定义

单例模式:是指在内存中值创建一个类的对象,让所有需要调用的地方都共享这个单例对象

单例模式有两种实现方式:

饿汉模式:是类创建的时候,就创建好了实例对象
懒汉模式:需要的时候再去创建

二、饿汉模式实现 1.优缺点:

优点:因为饿汉模式是提前创建好对象,所以是线程安全的
缺点:不管系统需不需要这个创建对象,它都会创建出对象,所以会造成内存空间的浪费。

2.代码实现:
#include
using namespace std;

//饿汉模式
class Singleton {
private:
	Singleton() {
		cout << "创建了一个单例对象" << endl;
	}
	static Singleton* instance;  //静态数据成员在类内声明
	~Singleton() {
		cout << "销毁了一个单例对象" << endl;
	}
public:
	static Singleton* getinstance() {
		return instance;
	}
	static void destroy() {  //需要自定义一个销毁函数
		cout << "销毁了一个单例对象(自定义销毁)" << endl;
		delete instance;
	}
};
Singleton* Singleton::instance = new Singleton(); //静态数据成员在类外进行定义初始化
int main() {
	cout << "now we get the instance" << endl;
	Singleton* s1 = Singleton::getinstance();
	Singleton* s2 = Singleton::getinstance();
	Singleton* s3 = Singleton::getinstance();
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;  //三个输出的地址都是一样的,即当创建一个对象后,再次创建对象时地址是一样的,说明单例模式返回的是同一个对象

	cout << "now we destroy the instance" << endl;
	Singleton::destroy();
	//饿汉模式,从输出可以看出,虽然代码中写了s1,s2,s3,但是程序只创建了一个对象。

return 0; }

运行结果如下:

三、懒汉模式 1.优缺点:

优点:系统需要的时候再去创建,不会存在内存浪费问题
缺点:当系统中有多个线程运行时,若同时检测到未创建实例对象,则这两个线程都会创建对象,那么此时就不再是单例模式,报错,所以存在线程安全问题。

所以在创建对象的时候需要加锁,来避免错误的产生。

2.代码实现

示例中模拟随机多线程实现,通过锁来解决懒汉模式下的存在的线程安全问题。

//懒汉模式  需要考虑线程安全问题
#include
#include
#include
#include
#include
#include
using namespace std;

mutex my_mutex; //创建一个线程
class Singleton {
private:
	Singleton() {
		cout << "创建了一个单例对象" << endl;
	}
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
	~Singleton() {
		cout << "销毁了一个单例对象" << endl;
	}
	static Singleton *instance;
public:
	static Singleton *getinstance() {
		if (instance == NULL) {
			my_mutex.lock();
			if (instance == NULL) {
				instance = new Singleton();
			}
		}
		return instance;
	}
	static void destroy() {
		cout << "销毁了一个单例对象(自己定义)" << endl;
		delete instance;
	}
};
Singleton* Singleton::instance = NULL;
void func1() {
	int num = rand() % 10;
	Sleep(num * 10);
	cout << "另外1个线程" << endl;
	Singleton* s1 = Singleton::getinstance();

	cout <<s1 << endl;
	Singleton::destroy();
	return;
}
void func2() {
	int num = rand() % 10;
	Sleep(num * 10);
	cout << "另外2个线程" << endl;
	Singleton* s2 = Singleton::getinstance();
	cout << s2 << endl;

	Singleton::destroy();
	return;
}
void func3() {
	int num = rand() % 10;
	Sleep(num * 10);
	cout << "另外3个线程" << endl;
	Singleton* s3 = Singleton::getinstance();
	cout << s3 << endl;
	Singleton::destroy();
	return;
}

int main() {
	cout << "now we get the instance" << endl;
	thread other1(func1);
	thread other2(func2);
	thread other3(func3);
	cout << "now we destroy the instance" << endl;
	other1.join();
	other2.join();
	other3.join();
	Singleton::destroy();
}

运行结果:

四、应用场景

(1)表示文件系统的类,一个 *** 作系统一定只是一个文件系统,因此文件系统的类的示例有且仅有一个。


(2)打印机打印程序的实例,通过单例模式避免两个打印作业同时输出到打印机。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/662348.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-18
下一篇 2022-04-18

发表评论

登录后才能评论

评论列表(0条)

保存