文章目录
- 什么是单例模式?
- 单例模式中的饿汉模式
- 单利模式中的懒汉模式
什么是单例模式?
保证一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享
单例模式中的饿汉模式
- 饿汉模式:单例定义的时候就进行实力化(空间换时间的做法),不管需不需要用到实例都要去创建实例,在类产生的时候就创建好实例,体现了我全都要的特性
- 在饿汉模式中,实例对象存储在全局数据区,所以用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++11Object& 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++11Object& 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++11Object& 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);
}