我与单例模式的碰撞
介绍
单例模式
单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式方法创建的类在当前进程种只会存在一个实例
应用场景
- 配置管理
- 日志记录
- 线程池
- 连接池
- 内存池
- 对象池
- 消息队列
实现步骤
- 将类的构造方法定义为私有方法
- 定义一个私有的类的静态实例
- 提取一个公有的获取实例的静态方法
涉及知识点
- Static修饰静态成员变量
- static修饰静态成员函数
- template 模板类
- friend友元类
设计与实现
常用实现
学习资料
实现单例模式的.h
// SingletonPatternVs.h: 标准系统包含文件的包含文件
// 或项目特定的包含文件。
#pragma once
#include <iostream>
// 创建单例模式
using namespace std;
/*第一个版本,最简单的版本*/
class SingleClass
{
private:
// 1、构造、析构函数私有化
SingleClass();
~SingleClass();
// 4、关闭拷贝构造函数和赋值运算符,在private中调用,避免外部进行调用
SingleClass(const SingleClass& other) = delete;
SingleClass& operator=(const SingleClass& other) = delete;
private:
// 2、声明一个静态变量用于存储实例的指针,并初始为nullptr
static SingleClass* Buf_SingleClass;
public:
// 创建函数
void func();
// 3、创建公共的静态成员函数获取实例对象
static SingleClass* getInstance();
};
实现单例模式的.cpp
#include "SingletonPatternVs.h"
SingleClass* SingleClass::Buf_SingleClass = nullptr;
SingleClass::SingleClass()
{
std::cout << "构造函数被调用" << std::endl;
}
SingleClass::~SingleClass()
{
std::cout << "析构函数被调用" << std::endl;
}
SingleClass* SingleClass::getInstance()
{
if (Buf_SingleClass == nullptr)
Buf_SingleClass = new SingleClass();
return Buf_SingleClass;
}
void SingleClass::func()
{
cout << "自定义函数,地址 == " << this << endl;
}
实现调用
#include "SingletonPatternVs.h"
int main(int argc, char* argv)
{
SingleClass* a = SingleClass::getInstance();
a->func();
return 0;
}
线程安全
模板实现
涉及知识点的学习
Static修饰静态成员变量
讲解static修饰静态成员变量
接下来,谈谈个人的理解
针对于static修饰的成员变量共存在以下几点特征
1:static成员变量属于类,不属于某一个具体的对象,即便你去创建多个对象,多个对象共享一片内存,也就是说,该进程只为该变量分配一份内存空间。当某个对象修改了该变量,那么也会影响到其他对象
2:static修饰的成员变量。必须在类声明之外进行初始化。格式:type class::name = value
3:static成员变量的内存既不是在声明类时分配,也不是在创建对象时分配,而是在类外初始化时进行分配空间。直接来讲:没有在类外初始化的static成员变量不能使用
4:初始化也可以赋值,也可以不赋值。默认为0。因为当变量使用static修饰的时候,会将内存定级为全局变量。全局变量中的默认初始值==0
qustion
问:静态成员可以使用非静态成员进行初始化嘛?
答:不可以。它本身的初始化是在类外部进行。而在初始化的时候,类还未进行实现
static修饰静态成员函数
讲解static修饰成员函数
接下来,谈谈个人的理解
1:普通函数可以访问所有成员(包括成员函数、成员变量),静态程序函数只能访问静态成员变量
2:编译器在编译普通成员函数的时候,会隐式的增加一个this指针,并把当前对象的地址赋值给this,因此调用普通成员函数的时候只能在创建对象后使用。因为它需要当前地址,
3:静态成员变量可以通过类来直接调用,编译器在编译的时候不会给他新增一个this指针。因为它不需要当前对象的地址。所以来讲,不管有没有创建对象,都可以通过类来调用静态成员函数
4:静态成员函数与普通成员函数的根本就在于:普通成员函数有this指针,因此它可以访问所有的成员。静态成员函数没有,只能访问静态成员
5:同静态成员变量一致,无论创建多少对象,它们都只会存在一个副本
6:静态成员函数不能够被const修饰(静态成员函数与类的静态成员变量和静态成员函数相关,与对象本身的状态无关)
7:静态成员函数不能够被声明为virtual,因为虚函数需要通过虚函数表进行动态绑定。而静态成员函数不存在this指针,因此无法实现动态绑定