单例模式简析
来源:互联网 发布:台湾政治知乎 编辑:程序博客网 时间:2024/05/21 07:48
一、单例模式
单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。
特点就是多读单写。
函数简单实现:
classSingleton
{
public:
staticSingleton*GetInstance()//申明为static,可以由对象直接调用,不用用类调用
{
if(_sInstance ==NULL)
{
_sInstance =newSingleton;
}
return_sInstance;
}
voidprintf()
{
cout << _data << endl;
}
protected:
Singleton()
:_data(0)
{}
//防拷贝,只申明不定义
Singleton(Singleton&);
Singleton&operator=(Singleton&);
//指向实例的指针定义为静态私有,这样定义静态成员函数获取对象实例
staticSingleton* _sInstance;
private:
int_data;
};
Singleton*Singleton::_sInstance = NULL;//初始化
intmain()
{
Singleton::GetInstance()->printf();
return0;
}
二、基于线程安全的改进
若有两个线程同时访问单例模式获取对象的方法,thread1执行方法,第一次进入发现指针为NULL,在还没有new之前,thread2也进入,这样就不能保证只有一个对象被创建,且第二个创建的对象将第一个创建的对象覆盖
解决方法:
1、懒汉模式
调用对象时才产生实例对象
改进
staticSingleton*GetInstance()
{
if(_sInstance ==NULL)//保证效率
{
_mx.lock();//保证线程安全
if(_sInstance ==NULL)
{
_sInstance =newSingleton;
//解法:RAII 2.用库函数的guard
}
_mx.unlock();
}
return_sInstance;
}
新增static成员对象
staticmutex_mx;
在类外需要初始化
mutexSingleton::_mx
但是,这么做有会引入新的问题,即当发生new失败时,则会发生抛异常, 而抛异常则会导致死锁。
解决方法:可以使用RAII,自动析构,guard
staticSingleton*GetInstance()
{
if(_sInstance ==NULL)//保证效率
{
lock_guard<mutex> lock(_mx);
if(_sInstance ==NULL)
{
_sInstance =newSingleton;//new 有可能会抛异常,若抛异常则导致死锁,但是用lock_guard可以出作用域自动析构
}
}
return_sInstance;
}
2、饿汉模式
最开始就创建对象
既线程安全,又高效
指针为静态,在main函数之前初始化,
classSingleton
{
public:
staticSingleton*GetInstance()
{
assert(_sInstance);
return_sInstance;
}
voidprintf()
{
cout << _data << endl;
}
protected:
Singleton()
:_data(0)
{}
//防拷贝,只申明不定义
Singleton(Singleton&);
Singleton&operator=(Singleton&);
//指向实例的指针定义为静态私有,这样定义静态成员函数获取对象实例
staticSingleton* _sInstance;
private:
int_data;
};
Singleton*Singleton::_sInstance = new Singleton;
三、关于面试题
1、定义一个类,只能在堆上生成对象
classA
{
public:
A*GetObj()
{
returnnewA;
}
private:
A()
{}
A(constA&);
};
2、定义一个类,只能在栈上生成对象
classA
{
private:
void*operator new (size_t);
voidoperator delete(void*p);
void*operator new[](size_t);
voidoperator delete[](void*p);
private:
inta;
};
0 0
- 单例模式简析
- 单例模式简析
- 单例模式简析
- 单例模式简析
- 单例模式及应用简析
- JAVA单例设计模式简析
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 单例模式简说--niu
- 单例模式的自动析构
- C++单例模式及其析构
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- node.js使用记录
- Qt之界面换肤
- 阿里云Linux系统挂载数据盘
- setImageResource和setBackgroundResource的区别
- ie 7 float right 换行
- 单例模式简析
- Android 如何正确使用我们的图片资源
- Java语言--读取文件中的内容
- 使用MyEclipse自动生成hibernate的数据库表
- 建议18:foreach不能代替for
- 用redis实现消息队列
- eclipse离线安装velocity插件
- WCF 基础连接已经关闭: 接收时发生错误
- C# mysqlcheck 检查数据库异常+修复数据库