C++InterViewCode
目录
>饿汉式是指系统一运行,就初始化创建实例,当需要时,直接调用即可。
# 参考
- 前言
- 正文
- 1. 单例模式
前言
这里就存储一些代码型的面试题,防止出一些现场手写的问题。
正文
1. 单例模式
其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。单例模式分为懒汉式和饿汉式。
懒汉式是在指系统运行中,实例并不存在,只有当需要该实例时,才创建该实例。但注意,懒汉式并不是线程安全的,若要达到线程安全,则一个进行加锁。
懒汉式
#include
#include
#include
using namespace std;
classs SignleInstance
{
public:
//获取单例对象
static SingleInstance *GetInstance();
//释放单例,进程退出时调用
static void deleteInstance();
//打印单例地址
void Print();
private:
//将其构造和析构函数都变成私有的,精致外部构造和析构
SingleInstance();
~SingleInstance();
//将拷贝构造和赋值构造成为私有函数,禁止外部拷贝和赋值
SingleInstance(const SingleInstance &signal);//拷贝构造
const SingleInstance &operator(const SingleInstance &signal);//const 防止对实参的意外修改
//使用引用的原因
// 因为实参是通过按值传递机制传递的。在可以传递对象cigar之前,编译器需要安排创建该对象的副本。因此,编译器为了处理复制构造函数的这条调用语句,需要调用复制构造函数来创建实参的副本。但是,由于是按值传递,第二次调用同样需要创建实参的副本,因此还得调用复制构造函数,就这样持续不休。最终得到的是对复制构造函数的无穷调用。(其实就是创建副本也是需要调用复制构造函数的)
//所以解决办法先是要将形参改为引用形参:
private:
//唯一实例对象指针
static SingleInstance *m_SingleInstance;
static mutex m_Mutex;
};
//初始化静态成员变量
SingleInstance *SingleInstance::m_SingleInstance = NULL;
mutex SingeInstance::m_Mutex;
SingleInstance* SingleInstance::GetInstance()
{
//使用双检锁的方式 ,判断对象为空再进行加锁
if(m_SingleInstance ==NULLL)
{
unique_lock lock;
if(m_SingleInstance ==NULLL)
m_SingleInstance = new (std::nothrow) SingleInstance;//线程并发的话有可能创建多个实例,非线程安全
}
return m_SingleInstance;
}
void SingleInstance::deleteInstance()
{
unique_lock lock
if(m_SingleInstance)
{
delete m_SingleInstance;
m_SingleInsance = NULL;//若没有置空,容易出现野指针。
}
}
void SingleInstance::Print()
{
std::cout<<"我的实例内存地址是"<
饿汉式
//初始化静态成员变量
#if 0 懒汉模式
SingleInstance *SingleInstance::m_SingleInstance = NULL;
#endif
#if 0 饿汉模式
SingleInstance *SingleInstance::m_SingleInstance = new(nothrow) SingleInstance;
#endif
mutex SingeInstance::m_Mutex;
SingleInstance* SingleInstance::GetInstance()
{
#if 0 懒汉模式
//使用双检锁的方式 ,判断对象为空再进行加锁
if(m_SingleInstance ==NULLL)
{
unique_lock lock;
if(m_SingleInstance ==NULLL)
m_SingleInstance = new (std::nothrow) SingleInstance;//线程并发的话有可能创建多个实例,非线程安全
}
#endif
#if 0 饿汉模式
return m_SingleInstance;//get方法,就直接返回即可。
#endif
}