当前位置: 首页 > news >正文

C++的特殊类

一、单例模式

        单例模式,是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来获取该实例。要确保只有一个实例,关键就是要ban掉构造函数以及拷贝构造和赋值拷贝,防止出现更多实例。

        在ban掉构造函数以后,要如何创建出唯一的一个实例呢?只能从静态变量这个角度来想办法解决。从单例模式的应用场景入手,单例模式通常用来统一写入日志文件、对共享设备统一管理等。因此,有饿汉模式和懒汉模式两种角度的实现方法:

1.1 饿汉模式

        饿汉模式,就是在程序启动时就完成单例的实例化,因此,无论是否会用到这个单例,只要使用了饿汉模式,程序启动,这个单例就会占用空间。但是,优势就是调用快速,实现简单:

class A {
public:static A& getA() {return a;}void Insert(pair<string, string> p) {mss.insert(p);}void Print() {for (auto& e : mss) {cout << e.first << ":" << e.second << endl;}}A& operator=(const A& a) = delete;A(const A& a) = delete;
private:A(){ }map<string, string> mss;static A a;
};A A::a;int main(void) {A::getA().Insert(make_pair("apple", "苹果"));A::getA().Insert(make_pair("banana", "香蕉"));A::getA().Insert(make_pair("cat", "猫"));A::getA().Insert(make_pair("delete", "删除"));A::getA().Print();return 0;
}

        通过在main之前实例化静态成员变量a,再借助调用函数就可以实现单例模式的饿汉模式,全局仅有一个A的实例,因此所有的插入都是在同一个map中进行修改。

1.2 懒汉模式

        懒汉模式,则是在需要调用时才会实例化,相比饿汉模式,能控制各个单例初始化的顺序,并且由于是调用时才会实例化,没有用到的类就不会被实例化出来占用空间,且可以节省在调用main函数之前的准备时间。缺点就是第一次调用时需要时间实例化,实现更为复杂:

class B {
public:static B* getB() {if (!pb) {pb = new B;}return pb;}void Add(const string& key, const string& value){m[key] = value;}void Print(){for (auto& kv : m){cout << kv.first << ":" << kv.second << endl;}cout << endl;}private:B(){ }~B() {cout << "把数据写入硬盘" << endl;}B(const B&) = delete;B& operator=(const B&) = delete;map<string, string> m;class gc {public:~gc() {delete pb;pb = nullptr;cout << "~B" << endl;}};static gc _gc;static B* pb;
};B* B::pb = nullptr;
B::gc B::_gc;int main(void) {B::getB()->Add("apple", "苹果");B::getB()->Add("banana", "香蕉");B::getB()->Add("cat", "猫");B::getB()->Add("delete", "删除");B::getB()->Print();return 0;
}

        这里用指针的形式实现懒汉模式,其实还有另一种采用静态局部变量的形式,也就是将饿汉模式的静态成员变量,放到get函数,在调用时如果没有实例化过则会实例化,如果实例化了就不会再实例化了,这里不做过多介绍。

        然后,指针的销毁通过智能指针的思想进行解决,也可以直接使用指针指针进行管理,当程序结束时,就会调用析构函数将指针销毁。这里是使用了一个静态类完成对静态指针的管理。

二、一些其他类型类的实现

2.1 不能被继承的类

        在C++98中,可以通过将父类的构造函数私有化来实现,而在C++11中则可以通过使用final关键字实现不能被继承。

2.2 不能被拷贝的类

        在C++98中,可以将拷贝构造和赋值拷贝声明在private下,这样既不能被调用,又不能在类外重写。而在C++11中,则可以简单的使用delete删除掉这两个函数,从而实现不能被拷贝。

2.3 只能在堆上创建的类

        同样也要通过限制构造函数来达成目的,再通过特定的可供调用的函数来完成构造。然后再删除掉拷贝构造和赋值拷贝,限制其他构造的手段:

class A {
public:static A* Initial(int a) {return new A(a);}
private:A(int a):_a(a){}A(const A&) = delete;A& operator=(const A&) = delete;int _a;
};

        这样就只能通过调用A::Initial函数完成构造 ,而这样构造出的类一定是堆上的类。

2.4 只能在栈上创建的类

        还是通过限制构造函数,但是,禁止掉拷贝构造函数会导致调用的构造函数无法传回构造出的类。因此,直接禁止掉new:

class A {
public:static A Initial(int a) {A tmp = A(a);return tmp;}A(A&&) = default;A& operator=(A&&) = default;
private:A(int a):_a(a){}void* operator new(size_t) = delete;A(const A&) = delete;A& operator=(const A&) = delete;int _a;
};

         这样,要在堆上创建就只能调用new但是new又被删除了,因此,只能在栈上创建。

http://www.lryc.cn/news/578209.html

相关文章:

  • STM32——DAP下载程序和程序调试
  • (4)pytest-fixture
  • Go语言安装使用教程
  • 深度剖析 LNK 参数隐藏攻击 (ZDI-CAN-25373)
  • 【甲方安全建设】敏感数据检测工具 Earlybird 安装使用详细教程
  • 门控循环单元(GRU):LSTM 的轻量级高效 “记忆专家”
  • Instrct-GPT 强化学习奖励模型 Reward modeling 的训练过程原理实例化详解
  • beforeRouteLeave 的触发本质
  • 2025年6月个人工作生活总结
  • 字节跳动 C++ QT PC客户端面试
  • 机器人仿真(1)Ubuntu24.04下CLion的ROS2开发环境配置
  • C++ 快速回顾(五)
  • 接口测试之接口关联
  • OpenCV CUDA模块设备层----- 正切(tangent)运算函数tan()
  • 一文讲清楚React中类组件与函数组件的区别与联系
  • C/C++ 使用rapidjson库 操作Json格式文件(创建、插入、解析、修改、删除)
  • 【2025最新】Ubuntu22.04 安装 MySQL8.0 教程
  • 零成本接入+企业级部署:2025年AI大模型实战指南
  • Linux云计算基础篇(2)
  • 对称非对称加密,https和http,https通讯原理,Charles抓包原理
  • 三态门Multisim电路仿真——硬件工程师笔记
  • 大模型在多发性硬化预测及治疗方案制定中的应用研究
  • Python 安装使用教程
  • 探索未来AI的无限可能:使用oTTomator Live Agent Studio平台上的开源AI代理!
  • JSON-LD 开发手册
  • 衡石科技chatbot分析手册--钉钉数据问答机器人配置
  • 衡石科技使用手册-企业即时通讯工具数据问答机器人用户手册
  • java中agent的作用
  • 免费文件管理 智能转换GC-Prevue:PDF 转 Word 多种格式 一键完成
  • 云手机主要是指什么?