单例模式
单例模式是指在一个项目中用来创建独一无二的,只能够有一个实例的对象。
经典实现
由于大多数单例对象的存在时间都比main长,所以我们并不需要担心对象的释放。
class Singleton
{
public:
static Singleton* getInstance();
protected:
Singleton(){}
private:
static Singleton* singleton;
};
Singleton *Singleton::singleton = NULL;
Singleton* Singleton::getInstance()
{
if( singleton == NULL)
singleton = new Singleton();
return singleton;
}
通过一个让构造函数私有(或受保护)来拒绝一切直接的构造行为,然后提供一个借口用于创建和访问。
在此基础上,如果出现这样的代码:
Singleton s1(*Singleton::getInstance());
Singleton s2 = *Singleton::getInstance();
就可以通过拷贝构造函数来创建新的对象,所以我们同样要禁用对应的构造函数
private:
Singleton(const Singleton&);
Singleton& operator =(const Singleton&);
静态初始化实现
class Singleton
{
public:
static Singleton* getInstance();
protected:
Singleton(){}
private:
static Singleton* singleton;
};
Singleton *Singleton::singleton = new Singleton();
Singleton* Singleton::getInstance()
{
return singleton;
}
问题是过早创建消耗资源。
线程安全
简单的解决方式就是加锁。
class Lock
{
private:
mutex mtex;
public:
Lock(mutex m) : mtex(m)
{
mtex.Lock();
}
~Lock()
{
mtex.Unlock();
}
};
class Singleton
{
public:
static Singleton* getInstance();
protected:
Singleton(){}
private:
static Singleton* singleton;
static mutex m;
};
Singleton *Singleton::singleton = NULL;
Singleton* Singleton::getInstance()
{
Lock lock(m);
if(singleton == NULL)
singleton = new Singleton();
return singleton;
}
但经常访问会有效率问题。。。
双重检验加锁
class Lock
{
private:
mutex mtex;
public:
Lock(mutex m) : mtex(m)
{
mtex.Lock();
}
~Lock()
{
mtex.Unlock();
}
};
class Singleton
{
public:
static Singleton* getInstance();
protected:
Singleton(){}
private:
static Singleton* singleton;
static mutex m;
};
Singleton *Singleton::singleton = NULL;
Singleton* Singleton::getInstance()
{
//双重检验加锁
if(singleton == NULL )
{
Lock lock(m);
if(singleton == NULL)
singleton = new Singleton();
}
return singleton;
}
避免线程锁打开后有其他的线程已完成判断,所以还要在进行一次判断。
12/5修改了一些语法错误(我不是编译器里写出来的吗,怎么回事???)