单例模式: 一个类只能创建一个对象。
class A
{
private:
A() {
a = new A();
}
static A *a; // 创建一个静态对象,并对外不可访问
public:
// 通过静态函数返回一个A对象
static A* getA() {
return a;
}
};
A* A::a = NULL;
int main()
{
A* sp = A::getA(); // 获取一个单例对象
return 0;
}
将构造方法私有化,提供一个静态方法将创建好的对象返回给调用者。
懒汉式
// 懒汉式
class Singleton_lazy
{
private:
Singleton_lazy() { }
static Singleton_lazy* pSingleton;
public:
static Singleton_lazy* getInstance() {
if (pSingleton == NULL) {
pSingleton = new Singleton_lazy();
}
return pSingleton;
}
};
Singleton_lazy* Singleton_lazy::pSingleton = NULL;
每当调用静态方法获取的时候才去创建一个对象出来,所以叫懒汉式。
饿汉式
// 饿汉模式
class Singleton_hungry
{
private:
Singleton_hungry() { }
static Singleton_hungry* pSingleton;
public:
static Singleton_hungry* getInstance() {
return pSingleton;
}
};
Singleton_hungry* Singleton_hungry::pSingleton = new Singleton_hungry();
饿汉式的构造先于main函数执行,提前就创建好了一个对象等着获取,所以叫饿汉式。
单例对象释放
单例模式在整个程序中只生成一个对象在堆区,在程序结束的时候,系统会自动回收,所以不需要考虑释放内存。
如果非要手动释放,那就写个私有的析构吧。
单例对象遇到多线程
懒汉模式: 在调用者调用静态获取对象的方法时,多线程情况下有 if 判断都为 NULL的可能,那么就创建了不止一个对象,违背了“单例”。所以懒汉式是线程不安全的。
饿汉模式: 先创建好了一个对象等着调用者去调用,此时这个对象在多线程下作为竞争资源。所以在多线程模式下创建单例模式使用饿汉模式。