单例模式:
- 一个类只实例化一个对象
- 类的构造函数设置private或者protected
- 提供一个静态的 能获取类对象地址的 类指针(用静态类指针指向函数,函数内部获取类对象地址)
- 线程安全,但不管用不用的上都会先生成对象实例。
- 饿汉单例模式:
- 1.1:获取类对象方式问题
1. //静态的 类的指针指向getInstence()
static SingleHungryMod* getInstence() {
return object_;
}//调用到getInstence()函数时,返回object_,object_是类指针。
- 1.2:类对象初始化问题
//初始化-静态的指针SingleHungryMod类指针object_,创建对象。
SingleHungryMod* SingleHungryMod::object_ = new SingleHungryMod;
//静态类指针在main函数前执行初始化,那么类对象也就初始化在main函数之前。
- 1.3:类对象在main函数中调用的问题
1. //obj类指针指向 getInstence函数
SingleHungryMod* obj = SingleHungryMod::getInstence();
1.4:内存泄露问题
SingleHungryMod* SingleHungryMod::object_ = new SingleHungryMod; //手动new出来的堆空间需要解决空间释放问题
- 解决方法之一: 既然是静态类指针,new初始化的的对象,那么就手动delete释放;
*怎么设计释放?
也定义一个静态的类成员函数专门做释放操作
//类中定义
static void deleteObj()
//类外实现
void SingleHungryMod::deleteObj() {
if (object_ != nullptr) {
delete object_;
object_ = nullptr;
}
}
- 能不能在类的析构函数中释放呢?
答案是不行的,因为new出来的对象都没释放,那么就调用不到析构函数
- 1.5:饿汉单例模式的线程安全问题 饿汉单例模式是线程安全的 因为:在线程访问对象之前,对象已经生成了。
#include<iostream>
using namespace std;
//饿汉式单例模式
class SingleHungryMod
{
public:
//静态的 类的函数指针getInstence()
static SingleHungryMod* getInstence() {
return object_;
}
//定义手动释放指针的静态函数
static void deleteObj();
void show(){
cout << "SingelHungryMod::show() call " << endl;
}
private:
SingleHungryMod()
{
cout << "SingelHungeryMod() call " << endl;
}
SingleHungryMod(const SingleHungryMod& obj) {
*this = obj;
};
~SingleHungryMod() {
cout << " ~SingleHungryMod() call " << endl;
}
//定义-静态的指针SingleHungryMod类指针object_
static SingleHungryMod* object_;
};
//初始化-静态的指针SingleHungryMod类指针object_,创建对象。
SingleHungryMod* SingleHungryMod::object_ = new SingleHungryMod;
//单例饿汉模式下 内存泄露的问题
//解决方案:创建一个静态函数手动delete释放
void SingleHungryMod::deleteObj() {
if (object_ != nullptr) {
delete object_;
object_ = nullptr;
}
}
int main()
{
cout << "main() run... " << endl;
//obj类指针指向 getInstence函数指针
SingleHungryMod* obj = SingleHungryMod::getInstence();
cout << obj << endl;
obj->show();
SingleHungryMod* obj1 = SingleHungryMod::getInstence();
cout << obj1 << endl;
obj1->show();
//手动释放。解决单例饿汉模式下的内存泄露
SingleHungryMod::deleteObj(); //成功调用SingleHungryMod的析构函数;
return 0;
}