2021-09-10
复习
- 构造函数被class私有化,需要创建对象就必须能够访问到class的私有域,static共有成员可以做到。
- 类的静态成员只能在类外进行初始化,不能通过构造函数初始化
- 类的静态函数在类中进行声明 类外 或者 类内进行声明
- 静态成员函数无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数
1 单例模式的概念
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
比如在某个服务器程序中,该服务器的配置信息存放在一个文件 中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置 信息,这种方式简化了在复杂环境下的配置管理。
2 懒汉模式和饿汉模式的区别
饿汉模式
- 概念:就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。可以理解为是“空间换时间”
懒汉模式
- 概念::第一次使用实例对象时,才创建对象。可以理解为“时间换空间”。
3 懒汉模式实现
懒汉模式 实现记住以下三句话
1.
构造函数私有化
2.
定义一个 私有静态的成员对象,类型为当前类型的指针,并且在类外初始化为空指针(nullptr)
3.
定义一个static公有的成员函数,函数内部判断,单例为空创建后返回,非空直接返回单例,返回值类型为指针。
class SingleLazy
{
private:
static SingleLazy* Single_;//静态单例类
SingleLazy()
{
cout<<"调用构造函数"<<endl;
} //构造函数私有化
~SingleLazy()
{
cout << "调用析构函数" << endl;
}
public:
static SingleLazy* getInstance()//公有的方法访问
{
if (Single_ == nullptr)
{
Single_ = new SingleLazy;
}
return Single_;
}
};
//可以进行初始化 或者声明
SingleLazy* SingleLazy::Single_ = nullptr;
void test01()
{
SingleLazy* p1 = SingleLazy::getInstance();
SingleLazy* p2 = SingleLazy::getInstance();
if (p1 == p2)
{
cout<<"两个指针指向同一片内存区域,是单例!"<<endl;
}
else
{
cout<<"不是单例模式!"<<endl;
}
}
4 饿汉模式实现
1.
构造函数私有
2.
定义一个私有静态成员变量,类型为当前类类型指针,与懒汉不同的在类外直接new初始化。
3.
定义一个static共有的成员函数,函数内部返回单例,返回值类型为指针。不做任何判断
//饿汉式
class SingleHungry
{
private:
static SingleHungry* Single_;//静态单例类
SingleHungry()
{
cout << "调用构造函数" << endl;
} //构造函数私有化
~SingleHungry()
{
cout << "调用析构函数" << endl;
}
public:
//唯一的区别点在以下的代码
static SingleHungry* getInstance()//公有的方法访问
{
return Single_;
}
};
SingleHungry* SingleHungry::Single_ = new SingleHungry;
void test01()
{
SingleHungry* p3 = SingleHungry::getInstance();
SingleHungry* p4 = SingleHungry::getInstance();
if (p3 == p4)
{
cout << "两个指针指向同一片内存区域,是单例!" << endl;
}
else
{
cout << "不是单例模式!" << endl;
}
}
5 需要解决的两个问题
- 实例内存释放的问题
单例模式就是为了程序整个过程中只有一个实例,不会占用特别多的内存资源。所以当程序结束的时候,即使没有人工释放,系统也会释放掉单例。总结,无需考虑这个问题。
- 解决多线程破坏单例的问题
懒汉模式,当多个线程同时进入
if (Single_ == nullptr)
判断且来不及创建对象都通过判断,可能就会造成创建多个实例,解决这个问题的方法就是上锁。
6 总结
单例模式使用和原理起来并不难,理解起来简单。但是在实际项目中确实经常使用,特别是有适合配合数据库等等一起使用。
如有错误,欢迎指出。