单例模式
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;
}