C++单例模式

单例模式

1:什么是单例

我的理解:在程序运行期间,只构造一个实例,所有的使用都共享使用该实例

2:如何实现单例

单例的特性:

​ 1:全局唯一的对象 ==》用static成员变量或者作用域特性实现

​ 2:不允许用户去构造 ==》禁用构造函数,但是要保证自己能调用

​ 3:只提供相应的接口,不允许用户修改 ==》禁用相关的拷贝构造等

​ 4:多线程要安全,资源的释放 ==》加锁,同一作用域static对象释放在程序运行结束时调用对应的析构函数

利用static特性,实现单例模式.
	1:静态成员为所有对象共享,不属于某个单个实例
	2:静态成员必须在类外定义,不需要加static,声明时已经加过
	3:类静态成员即可用类名::静态成员或者对象.静态成员来访问
	4:静态成员函数没有隐藏的this指针,不能访问任何非静态成员
	5:静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值

单例的实现主要依赖static的特性实现!!!

3:编码实现

1: 在栈上控制内存的申请与释放,借助static特性(所有对象共享,不属于某个实例),实现懒汉和饿汉两种模式的单例

饿汉:

#include <iostream>
using namespace std;

class Singleton{
private:
	Singleton() = default;
	Singleton(const Singleton & s) = delete;
	Singleton &operator = (const Singleton &s) = delete;
	~Singleton(){};
private:
	static Singleton m_sig;

public:
	static Singleton * GetInstence()
	{
		return &m_sig;
	}

	void Print()
	{
		cout<<"Singleton Instence\n ";
	}
};

Singleton Singleton::m_sig; //饿汉

int main()
{
	Singleton::GetInstence()->Print();
	return 0;
}

懒汉: static为整个类服务,而不是某个对象,只初始化一次,而且生命周期延长到整个程序运行结束才释放,全局数据区分配内存

​ 修饰全局变量时,只能在本文件访问

#include <iostream>
using namespace std;

class Singleton{
private:
	Singleton() = default;
	Singleton(const Singleton & s) = delete;
	Singleton &operator = (const Singleton &s) = delete;
	~Singleton(){};

public:
	static Singleton * GetInstence() //调用这个函数的时候static生效了
	{
		static Singleton m_sig;
		return &m_sig;
	}

	void Print()
	{
		cout<<"Singleton Instence\n ";
	}
};

int main()
{
	Singleton::GetInstence()->Print();
	return 0;
}
2:可以利用static的特性,申请堆内存,相关的实现如下:

如下代码,借助static管理堆内存,但明显发现,new出来的资源是没有释放的,

#include <iostream>
#include <mutex>
using namespace std;

class Singleton{
private:
	Singleton() = default;
	Singleton(const Singleton & s) = delete;
	Singleton &operator = (const Singleton &s) = delete;
	~Singleton(){};

public:
	//对静态成员操作,所以控制成static
	static Singleton * GetInstence()
	{
		if(Singleton::m_sig_instance == NULL)
		{
			m_mutex.lock();
			if(Singleton::m_sig_instance == NULL)
			{
				m_sig_instance = new Singleton();
			}
			m_mutex.unlock();
		}
	}

	void Print()
	{
		cout<<"Singleton Instence.\n ";
	}

private:
	static Singleton * m_sig_instance;
	static std::mutex m_mutex;
};

Singleton * Singleton::m_sig_instance = NULL;
std::mutex Singleton::m_mutex;
int main()
{
	Singleton::GetInstence()->Print();
	return 0;
}

借助static的栈内存特性和类的作用域会调用析构函数,在类的作用域内用static特性实现资源的释放:

#include <iostream>
#include <mutex>
using namespace std;

class Singleton{
private:
	Singleton() = default;
	Singleton(const Singleton & s) = delete;
	Singleton &operator = (const Singleton &s) = delete;
	~Singleton(){};

	class FreeSingleton
	{
		public:
			~FreeSingleton()
			{
				cout<<"start free singletion \n";
				if(m_sig_instance != NULL)
				{
					cout<<"free singletion \n";
					delete m_sig_instance;
					m_sig_instance = NULL;
				}
			}
	};

public:
	//对静态成员操作,所以控制成static
	static Singleton * GetInstence()
	{
		if(Singleton::m_sig_instance == NULL)
		{
			m_mutex.lock();
			if(Singleton::m_sig_instance == NULL)
			{
				m_sig_instance = new Singleton();
			}
			m_mutex.unlock();
		}
	}

	void Print()
	{
		cout<<"Singleton Instence.\n ";
	}

private:
	static Singleton * m_sig_instance;
	static std::mutex m_mutex;
	static FreeSingleton m_freed;

};

Singleton * Singleton::m_sig_instance = NULL;
std::mutex Singleton::m_mutex;
//借助static 栈的特性,通过析构释放对应的内存 注意这里的类型和static变量的作用域取值
Singleton::FreeSingleton Singleton::m_freed; 

int main()
{
	Singleton::GetInstence()->Print();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值