您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页C++语法(26)--- 特殊类设计

C++语法(26)--- 特殊类设计

来源:化拓教育网


1.特殊类设计

2.单例模式

1.设计模式

设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

一些设计理念:迭代器模式,配接器模式,单例模式,工厂模式,观察者模式

2.单例模式

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
使用样例:内存池的申请

1.饿汉模式

特点:

一开始(在main函数之前)就创造对象,就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象

缺点:

1.由于初始化在main函数之前,这样的类数据过多,会使得启动慢;

2.多个单例类有初始化依赖关系,饿汉模式无法控制类的初始化先后关系

class InfoSingleton
{
public:
	static InfoSingleton& GetInstance()
	{
		return _sins;
	}

	void Insert(string name, int money)
	{
		_info[name] = money;
	}

	void Print()
	{
		for (auto kv : _info)
		{
			cout << kv.first << " " << kv.second << endl;
		}
	}

private:
	InfoSingleton()
	{}

	InfoSingleton(const InfoSingleton& info) = delete;

	InfoSingleton& operator=(const InfoSingleton& info) = delete;

	map<string, int> _info;

private:
	static InfoSingleton _sins;
};

InfoSingleton InfoSingleton::_sins;

int main()
{
	InfoSingleton::GetInstance().Insert("张三", 1000);
	InfoSingleton& info = InfoSingleton::GetInstance();
	info.Insert("李四", 100);
	//InfoSingleton copy = InfoSingleton::GetInstance(); //拷贝构造
	//copy.Insert("***", 10000);
	return 0;
}

2.懒汉模式

1.如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。

2.如果类之间存在依赖关系,也可以使用懒汉模式(延迟加载)。

template<class Lock>
class LockGuard
{
public:
	LockGuard(Lock& lk)
		:_lk(lk)
	{
		_lk.lock();
	}

	~LockGuard()
	{
		_lk.unlock();
	}

private:
	Lock& _lk;
};

class _InfoSingleton
{
public:
	//线程安全问题,多线程一起调用创建对象
	static _InfoSingleton& GetInstance()
	{
		//双检查增加效率
		if (_psins == nullptr) {
			LockGuard<mutex> lock(*_smtx);
			if (_psins == nullptr)
			{
				_psins = new _InfoSingleton;
			}
		}
		return *_psins;
	}

	void Insert(string name, int money)
	{
		_info[name] = money;
	}

	void Print()
	{
		for (auto kv : _info)
		{
			cout << kv.first << " " << kv.second << endl;
		}
	}

private:
	_InfoSingleton()
	{}

	_InfoSingleton(const _InfoSingleton& info) = delete;

	_InfoSingleton& operator=(const _InfoSingleton& info) = delete;

	map<string, int> _info;

private:
	static _InfoSingleton* _psins;
	static mutex* _smtx;
};

static _InfoSingleton* _psins = nullptr;
static mutex* _smtx;

1.这样写是懒汉模式,只创建一次,并且在main函数调用之后创建。

2.该代码有线程安全问题,在C++11后得到解决。

static _InfoSingleton& GetInstance()
{
	static _InfoSingleton sinst;
	return sinst;
}

注意:

1.懒汉模式需要注意线程安全问题,所以我们在类中需要有一个唯一的锁,确保判断时是串行访问的。

2.每次都先加锁再进行判断是否为空,其实是非常低效,所以我们需要双判断,第一次判断是为了抛去已经创建过的节省加锁的时间,第二次判断是为了创建对象使用的,而锁夹在中间确保第二次的判断是串行的。

3.饿汉模式不需要注意线程安全问题,因为饿汉在main调用之前就已经存在了,没有所谓的线程可以创建其他的对象。

3.单例对象释放问题

1.一般而言单例类不需要释放内存,因为单例出现的环境就是全局的,它的目的就是陪到进程执行到最后,那么其实不释放,进程结束后,操作系统也会将这一部分的资源回收。

2.特别的,如果我们需要在最后单例有一定要求,我们可以手写出析构,比如进程结束需要保存一些数据到文件中,那么我们析构可以手写要求。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务