什么是单例模式?
保证一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享
单例模式中的饿汉模式
- 饿汉模式:单例定义的时候就进行实力化(空间换时间的做法),不管需不需要用到实例都要去创建实例,在类产生的时候就创建好实例,体现了我全都要的特性
- 在饿汉模式中,实例对象存储在全局数据区,所以用static修饰,是线程安全的,因为在线程创建之前实例就已经创建好了。
class Object
{
private:
int value;
static Object obja;
private:
Object(int x = 0) :value(x) { cout << "Create Object" << endl; }
Object(const Object&) = delete; //C++11
Object& operator=(const Object&) = delete;
public:
~Object() { cout << "Destory Object" << endl; }
static Object& GetObj() //不能以值返回,因为拷贝构造函数也被设置为私有的了
{
return obja;
}
/*static Object* GetObj()
{
return obja;
}
*/
void SetValue(int x) { value = x; }
};
Object Object:: obja(10);//Object* object::obj=new obja();
int main()
{
Object& objecta = Object::GetObj(); //obja是全局变量,它的生命周期再局部函数结束时依然存在
Object& objectb = Object::GetObj();
objecta.SetValue(20);
objectb.SetValue(10);
}
单利模式中的懒汉模式
- 需要用到创建实例了才程序中创建实例,不需要创建实例程序就不去创建实例(时间换空间)
- 定义一个静态类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例
class Object
{
private:
int value;
static Object *pobja;
//static int x;
private:
Object(int x = 0) :value(x) { cout << "Create Object" << endl; }
Object(const Object&) = delete; //C++11
Object& operator=(const Object&) = delete;
public:
~Object() { cout << "Destory Object" << endl; }
static Object* GetObj() //不能以值返回,因为拷贝构造函数也被设置为私有的了
{
if (nullptr == pobja)
{
pobja = new Object(10);
}
return pobja;
}
void SetValue(int x) { value = x; }
};
Object* Object::pobja=nullptr;
//int Object::x = 10;
int main()
{
Object* p = Object::GetObj();
Object& objb = *Object::GetObj();
p->SetValue(10);
objb.SetValue(20);
return 0;
}
但是懒汉模式存在的问题:
在单线程下可以,但是在多线程下会线程发生资源争夺,导致线程不安全,所以我们需要进行加锁操作
static Object* GetObj() //不能以值返回,因为拷贝构造函数也被设置为私有的了
{
Lock();
if (nullptr == pobja)
{
pobja = new Object(10);
}
Unlock();
return pobja;
}
补充:这里我们将析构函数置位公有,当我们将析构函数也置位私有的时候,就会发现出现系统不会调用析构函数,这时出现了内存泄漏。
原因:在全局数据区的时候,存储的是一个实例对象的指针,真正的实例对象存放在堆区,我们需要手动释放资源,但也不能调用析构函数了
class Object
{
private:
int value;
static Object obja;
private:
Object(int x = 0) :value(x) { cout << "Create Object" << endl; }
Object(const Object&) = delete; //C++11
Object& operator=(const Object&) = delete;
public:
~Object() { cout << "Destory Object" << endl; }
static Object& GetObj() //不能以值返回,因为拷贝构造函数也被设置为私有的了
{
return obja;
}
static void deleteobj()
{
delete obja;
}
void SetValue(int x) { value = x; }
};
Object Object:: obja(10);//Object* object::obj=new obja();
int main()
{
Object& objecta = Object::GetObj(); //obja是全局变量,它的生命周期再局部函数结束时依然存在
Object& objectb = Object::GetObj();
objecta.SetValue(20);
objectb.SetValue(10);
}