所谓单例模式就是让一个类只能实例化一个对象。简单的单例模式如下:
class Singleton
{
public:
static Singleton* getInstance()
{
if (NULL == object)//懒加载
{
object = new Singleton();
}
return object;
}
private:
Singleton() {}
Singleton(const Singleton&);//屏蔽拷贝构造函数
static Singleton *object;
};
Singleton* Singleton::object = NULL;
int main()
{
//s1,s2,s3实际上指向同一块内存,只生成了一个对象
Singleton* s1=Singleton::getInstance();
Singleton* s2=Singleton::getInstance();
Singleton* s3 = Singleton::getInstance();
//Singleton s4 = *s1;//调用的是拷贝构造函数,如果不屏蔽拷贝构造函数,则会生成第二个对象
return 0;
}
考虑多线程环境下可能会出错,应加锁来控制。
class Singleton
{
public:
static Singleton* getInstance()
{
pthread_mutex_lock(&mutex);
if (NULL == object)//懒加载
{
object = new Singleton();
}
pthread_mutex_unlock(&mutex);
return object;
}
private:
Singleton() {}
Singleton(const Singleton&);//屏蔽拷贝构造函数
static Singleton *object;
};
Singleton* Singleton::object = NULL;
由于可能存在单线程或多线程共存的场景,为了降低单线程获取释放锁的效率,可以使用双重if判断。
class Singleton
{
public:
static Singleton* getInstance()
{
if (NULL == object)
{
pthread_mutex_lock(&mutex);
if (NULL == object)//懒加载
{
object = new Singleton();
}
pthread_mutex_unlock(&mutex);
}
return object;
}
private:
Singleton() {}
Singleton(const Singleton&);//屏蔽拷贝构造函数
static Singleton *object;
};
Singleton* Singleton::object = NULL;
考虑编译器的指令优化和CPU的动态指令优化。volatile关键字阻止编译器为了提高速度将一个变量缓存到寄存器中而不写回内存,volatile关键字阻止编译器调整操作volatile变量的指令操作;barrier指令会阻止CPU对指令进行动态换序优化
class Singleton
{
public:
volatile static Singleton* getInstance()
{
if (NULL == object)
{
pthread_mutex_lock(&mutex);
if (NULL == object)//懒加载
{
Singleton* temp = new Singleton();
barrier();//防止CPU对指令进行动态换序优化,使对象的构造一定在barrier完成,因此赋值给object的对象使完好的
object = temp;
}
pthread_mutex_unlock(&mutex);
}
return object;
}
private:
Singleton() {}
Singleton(const Singleton&);//屏蔽拷贝构造函数
volatile static Singleton *object;
};
volatile Singleton* Singleton::object = NULL;