【C++ 学习 ㊲】- 五种特殊类的设计

目录

一、设计一个禁止拷贝的类

二、设计一个只能在堆区上创建对象的类

三、设计一个只能在栈区和静态区上创建对象的类

四、设计一个不能继承的类

五、设计一个只能创建一个对象的类(单例模式)


 


一、设计一个禁止拷贝的类

拷贝只会发生在两个场景中,分别是拷贝构造和赋值,因此想要让一个类禁止拷贝,只需要让该类对象不能调用拷贝构造函数以及赋值运算符重载即可

  1. C++98/03

    class CopyBan
    {
    public:CopyBan() { }
    private:CopyBan(const CopyBan& cb);CopyBan& operator=(const CopyBan& cb);
    };
    ​
    int main()
    {CopyBan cb1;// CopyBan cb2(cb1);  // error// CopyBan cb3;// cb3 = cb1;  // errorreturn 0;
    }
  2. C++11

    class CopyBan
    {
    public:CopyBan() { }CopyBan(const CopyBan& cb) = delete;CopyBan& operator=(const CopyBan& cb) = delete;
    };
    ​
    int main()
    {CopyBan cb1;// CopyBan cb2(cb1);  // error// CopyBan cb3;// cb3 = cb1;  // errorreturn 0;
    }


二、设计一个只能在堆区上创建对象的类

  1. 将类的构造函数设置为私有,同时禁止拷贝构造函数的生成,防止通过拷贝构造创建对象;最后提供一个创建堆对象的静态成员函数

    #include <iostream>
    using namespace std;class HeapOnly
    {
    public:static HeapOnly* Create(){return new HeapOnly;}
    private:HeapOnly(){cout << "HeapOnly()" << endl;}HeapOnly(const HeapOnly& ho) = delete;
    };int main()
    {// HeapOnly ho;  // error// static HeapOnly sho;  // errorHeapOnly* pho = HeapOnly::Create();  // HeapOnly()// HeapOnly copy(*pho);  // errordelete pho;return 0;
    }
  2. 将类的析构函数设置为私有,然后提供一个完成 delete 操作的静态成员函数

    #include <iostream>
    using namespace std;class HeapOnly
    {
    public:void Destroy(){delete this;}
    private:~HeapOnly(){cout << "~HeapOnly()" << endl;}
    };int main()
    {// HeapOnly ho;  // error// static HeapOnly sho;  // errorHeapOnly* pho = new HeapOnly;// HeapOnly copy(*pho);  // errorpho->Destroy();  // ~HeapOnly()return 0;
    }


三、设计一个只能在栈区和静态区上创建对象的类

  1. 将类的构造函数设置为私有,然后提供一个创建对象的静态成员函数

    #include <iostream>
    using namespace std;
    ​
    class StackStaticOnly
    {
    public:static StackStaticOnly CreateObj(){return StackStaticOnly();}
    private:StackStaticOnly(){cout << "StackStaticOnly()" << endl;}
    };
    ​
    int main()
    {StackStaticOnly sso = StackStaticOnly::CreateObj();  // StackStaticOnly()static StackStaticOnly ssso = StackStaticOnly::CreateObj();  // StackStaticOnly()// StackStaticOnly* psso1 = new StackStaticOnly;  // error// 注意:该方法无法防止以下的情况发生// StackStaticOnly* psso2 = new StackStaticOnly(sso);  // ok// 如果禁止拷贝构造函数的生成,会导致 CreateObj 函数发生错误return 0;
    }
  2. 直接禁止 operator new 和 operator delete 的生成

    class StackStaticOnly
    {void* operator new(size_t size) = delete;void operator delete(void* p) = delete;
    };
    ​
    int main()
    {StackStaticOnly sso;static StackStaticOnly ssso;// StackStaticOnly* psso1 = new StackStaticOnly;  // error// StackStaticOnly* psso2 = new StackStaticOnly(sso);  // errorreturn 0;
    }


四、设计一个不能继承的类

  1. C++98/03

    将基类的构造函数设置私有,派生类就无法调用基类的构造函数,因此无法继承

    class NonInherit
    {
    public:static NonInherit CreateObj(){return NonInherit();}
    private:NonInherit() { }
    };
  2. C++11

    使用 final 关键字修饰类,表示该类不能被继承

    class NonInherit final
    { };


五、设计一个只能创建一个对象的类(单例模式)

设计模式(Design Pattern)是一种针对软件设计中经常出现的问题和解决方案的标准化描述。它们可以被视为是经验丰富的软件开发人员在解决类似问题时总结出来的设计思路、原则和指导。设计模式帮助我们以一种可重用的方式来解决特定的设计问题,从而使代码更具灵活性、可维护性和可扩展性。

单例模式:一个类只能创建一个对象。该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。

单例模式有以下两种实现模式

  1. 饿汉模式

    在程序入口之前就完成了单例对象的初始化

    #include <iostream>
    using namespace std;
    ​
    class Singleton
    {
    public:// 提供一个获取单例对象的静态成员函数static Singleton& GetInstance(){return _ss;}
    private:// 将类的构造函数设置为私有Singleton() {cout << "Singleton()" << endl;}
    ​// 禁止拷贝构造函数的生成Singleton(const Singleton& s) = delete;
    ​static Singleton _ss;  // 注意:静态成员变量属于类,不属于某个具体的对象
    };
    ​
    Singleton Singleton::_ss;  // Singleton()
    ​
    int main()
    {cout << &Singleton::GetInstance() << endl;cout << &Singleton::GetInstance() << endl;// 输出的两个地址是相同的
    ​// Singleton copy(Singleton::GetInstance());  // errorreturn 0;
    }
  2. 懒汉模式

    如果单例对象构造十分耗时或者占用很多资源,比如加载插件、初始化网络连接、读取文件等等,而该对象在程序运行时又有可能不会用到,那么使用饿汉模式,在程序入口之前就完成单例对象的初始化,会导致程序启动时变得非常缓慢,所以在这种情况下使用懒汉模式(延迟加载)更好

    #include <iostream>
    using namespace std;
    ​
    class Singleton
    {
    public:static Singleton& GetInstance(){if (_pss == nullptr){_pss = new Singleton;}return *_pss;}
    ​// 一般情况下,单例对象是不需要释放的,// 特殊场景:// 1、中途需要显示释放// 2、程序结束时,需要做一些特殊动作,比如持久化static void DelInstance(){if (_pss){delete _pss;_pss = nullptr;}}
    private:Singleton(){cout << "Singleton()" << endl;}
    ​~Singleton(){cout << "~Singleton()" << endl;}
    ​Singleton(const Singleton& s) = delete;
    ​static Singleton* _pss;
    };
    ​
    Singleton* Singleton::_pss = nullptr;
    ​
    int main()
    {cout << &Singleton::GetInstance() << endl;cout << &Singleton::GetInstance() << endl;// Singleton()// 输出的两个地址是相同的
    ​// Singleton copy(Singleton::GetInstance());  // error
    ​Singleton::DelInstance();// ~Singleton()return 0;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/142542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IronSource 聚合广告平台接入踩坑日记——游戏声音消失

1.IOS 播放完广告之后&#xff0c;关闭广告&#xff0c;发现整个游戏的声音消失 解决方案&#xff1a; 1.取消勾选 Mute Other audio sources&#xff0c; 对于这个选项&#xff0c;官方的说法是&#xff1a; 运行 Unity 应用程序时&#xff0c;停止或允许在后台播放来自其…

基于51单片机PCF8591数字电压表数码管显示设计( proteus仿真+程序+设计报告+讲解视频)

PCF8591数字电压表数码管显示 1.主要功能&#xff1a;讲解视频&#xff1a;2.仿真3. 程序代码4. 设计报告5. 设计资料内容清单&&下载链接资料下载链接&#xff08;可点击&#xff09;&#xff1a; 基于51单片机PCF8591数字电压表数码管设计( proteus仿真程序设计报告讲…

Vue3-TypeScript-Threejs:导入外部的glb格式3D模型

一、直接上代码&#xff0c;在vue3-typescript-threejs 项目 导入外部的glb格式3D模型 极简代码&#xff0c;快速理解 <template><div ref"container"></div></template><script lang"ts" setup>import { onMounted, ref …

IEEE--DSConv: Efficient Convolution Operator 论文翻译

论文地址:https://arxiv.org/pdf/1901.01928v1.pdf 目录 摘要 1 介绍 2 相关工作 3 DSConv层 4 量化过程 5 分布偏移 6 优化推断 7 训练 8 结果 8.1 ImageNet 8.2 内存和计算负载 8.3 转移性 9 结论 摘要 我们引入了一种卷积层的变体&#xff0c;称为DSConv&…

cmd打开idea

当我们用idea打开一个项目的时候&#xff0c;有时候这个项目目录是有的&#xff0c;但是用idea的open却找不到&#xff0c;有时候我要重新关闭窗口&#xff0c;再open好多次才有 于是我现在使用命令打开&#xff0c;先把idea安装路径的bin目录放在path里面 然后cd到项目路径&…

Linux操作系统使用及C高级编程-D3Linux shell命令(权限、输入输出)

Shell 是一种应用程序&#xff0c;用以完成用户与内核之间的交互 一个功能强大的编程语言&#xff08;C语言&#xff09; 一个解释执行的脚本语言&#xff0c;不需要编译&#xff0c;写完直接执行 目前Linux 乌班图的Shell默认是bash 查看当前提供的Shell&#xff1a;cat /…

Tomcat隐藏版本号和关闭默认管理页面

一. 隐藏Tomcat异常页面中的版本信息&#xff0c;Tomcat服务器版本号泄露 Tomcat/8.5.xx相关版本号等信息&#xff0c;是不安全的。这会被黑客获取到&#xff0c;利用该版本的其他漏洞对服务器进行异常操作&#xff0c;所以需要隐藏掉。 进入tomcat安装目录 apache-tomcat-8.…

怎么在uni-app中使用Vuex 深度解刨

本文深入研究Vuex,一个Vue.js状态管理库。我们将介绍创建它是为了解决的问题、其背后的核心概念、如何设置它,当然,还将在每一步中使用代码示例。 Vuex是一个由Vue团队构建的状态管理库,用于管理Vue.js应用程序中的数据。它提供了一种集中管理跨应用程序使用的数据的方式,…

设计模式-备忘录模式(Memento)

设计模式-备忘录模式&#xff08;Memento&#xff09; 一、备忘录模式概述1.1 什么是备忘录模式1.2 简单实现备忘录模式1.3 使用备忘录模式的注意事项 二、备忘录模式的用途三、备忘录模式实现方式3.1 基于数组的备忘录实现方式3.2 基于集合的备忘录实现方式3.3 基于HashMap的备…

如何修改文件的修改时间?

如何修改文件的修改时间&#xff1f;随着当代社会科技的不断进步&#xff0c;我们对信息和数据的依赖程度与日俱增。在这个信息化时代&#xff0c;文件处理已经成为数字化办公中不可或缺的一部分。文件处理的范围非常广&#xff0c;其中有一个比较冷门的操作技巧&#xff0c;那…

《QT从基础到进阶·二十三》弹窗提示框QMessageBox和QCloseEvent事件

1、正常信息提示 QMessageBox::information(NULL, "Title", "Content", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);消息框按钮判断&#xff1a; if(QMessageBox::Ok QMessageBox::warning(this,"温馨提示","是否保存设置?…

智慧工地管理云平台源码,Spring Cloud +Vue+UniApp

智慧工地源码 智慧工地云平台源码 智慧建筑源码支持私有化部署&#xff0c;提供SaaS硬件设备运维全套服务。 互联网建筑工地&#xff0c;是将互联网的理念和技术引入建筑工地&#xff0c;从施工现场源头抓起&#xff0c;最大程度的收集人员、安全、环境、材料等关键业务数据&am…

光纤网络排障分析

日常工作中&#xff0c;发现某条光链路连接不稳定&#xff0c;时快时慢、时断时连。 在交换机上直接查看这条链路交换口上的光收发功率&#xff0c;发现异常。 简单说明下&#xff0c;RX Power代表光模块接收功率&#xff0c;TX Power代表发送功率。 引起这种故障的原因很多&a…

Java实现身份证号校验,最后一位校验码校验

中国居民身份证号码编码规则 第一、二位表示省&#xff08;自治区、直辖市、特别行政区&#xff09;。 第三、四位表示市&#xff08;地级市、自治州、盟及国家直辖市所属市辖区和县的汇总码&#xff09;。其中&#xff0c;01-20&#xff0c;51-70表示省直辖市&#xff1b;21-5…

c# 将excel导入 sqlite

nuget 须要加载 EPPlus.Core ExcelDataReader ExcelDataReader.DataSet //需要引用的扩展 using ExcelDataReader; using ExcelPackage OfficeOpenXml.ExcelPackage; public static void CreateZhouPianChaTable(){string tbname "zhou_pian_cha1";//判断表是否存…

Elasticsearch 面试题

文章目录 Elasticsearch 读取数据您能解释一下 X-Pack for Elasticsearch 的功能和重要性吗&#xff1f;Elasticsearch 中的节点&#xff08;比如共 20 个&#xff09;&#xff0c;其中的 10 个选了 一个master&#xff0c;另外 10 个选了另一个 master&#xff0c;怎么办&…

嵌入式杂记 -- MCU的大小端模式

MCU的大小端模式 大端模式小端模式大小端模式测试联合体概念MCU大小端模式测试大端模式测试小端模式测试 大小端模式转换 在进行MCU开发的时候&#xff0c;我们需要注意MCU的数据存储模式&#xff0c;在嵌入式中有两种不同的存储模式&#xff0c;分别是 大端模式和小端模式。 …

Linux 函数库

函数库&#xff1a; 我们的C程序中&#xff0c;并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢? 最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去…

数据结构 | 带头双向循环链表专题

数据结构 | 带头双向循环链表专题 前言 前面我们学了单链表&#xff0c;我们这次来看一个专题带头的双向循环链表~~ 文章目录 数据结构 | 带头双向循环链表专题前言带头双向循环链表的结构实现双向链表头文件的定义哨兵位初始化创建节点尾插尾删头插头删打印查找指定位置前插入…

CSS BFC是什么,应用实例

CSS BFC&#xff08;块级格式化上下文&#xff09;是一个Web页面渲染时生成的一种独立的渲染区域&#xff0c;它定义了一套渲染规则&#xff0c;用于控制块级盒子的布局和浮动元素与其他元素的交互。BFC可以避免出现一些常见的布局问题&#xff0c;提高页面的可靠性和可维护性。…