【C++ 学习 ㊲】- 五种特殊类的设计
目录
一、设计一个禁止拷贝的类
二、设计一个只能在堆区上创建对象的类
三、设计一个只能在栈区和静态区上创建对象的类
四、设计一个不能继承的类
五、设计一个只能创建一个对象的类(单例模式)
一、设计一个禁止拷贝的类
拷贝只会发生在两个场景中,分别是拷贝构造和赋值,因此想要让一个类禁止拷贝,只需要让该类对象不能调用拷贝构造函数以及赋值运算符重载即可。
-
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; } -
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; }
二、设计一个只能在堆区上创建对象的类
-
将类的构造函数设置为私有,同时禁止拷贝构造函数的生成,防止通过拷贝构造创建对象;最后提供一个创建堆对象的静态成员函数。
#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; } -
将类的析构函数设置为私有,然后提供一个完成 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; }
三、设计一个只能在栈区和静态区上创建对象的类
-
将类的构造函数设置为私有,然后提供一个创建对象的静态成员函数。
#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; } -
直接禁止 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; }
四、设计一个不能继承的类
-
C++98/03:
将基类的构造函数设置私有,派生类就无法调用基类的构造函数,因此无法继承。
class NonInherit { public:static NonInherit CreateObj(){return NonInherit();} private:NonInherit() { } }; -
C++11:
使用 final 关键字修饰类,表示该类不能被继承。
class NonInherit final { };
五、设计一个只能创建一个对象的类(单例模式)
设计模式(Design Pattern)是一种针对软件设计中经常出现的问题和解决方案的标准化描述。它们可以被视为是经验丰富的软件开发人员在解决类似问题时总结出来的设计思路、原则和指导。设计模式帮助我们以一种可重用的方式来解决特定的设计问题,从而使代码更具灵活性、可维护性和可扩展性。
单例模式:一个类只能创建一个对象。该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
单例模式有以下两种实现模式:
-
饿汉模式:
在程序入口之前就完成了单例对象的初始化。
#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; } -
懒汉模式:
如果单例对象构造十分耗时或者占用很多资源,比如加载插件、初始化网络连接、读取文件等等,而该对象在程序运行时又有可能不会用到,那么使用饿汉模式,在程序入口之前就完成单例对象的初始化,会导致程序启动时变得非常缓慢,所以在这种情况下使用懒汉模式(延迟加载)更好。
#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; }
相关文章:
【C++ 学习 ㊲】- 五种特殊类的设计
目录 一、设计一个禁止拷贝的类 二、设计一个只能在堆区上创建对象的类 三、设计一个只能在栈区和静态区上创建对象的类 四、设计一个不能继承的类 五、设计一个只能创建一个对象的类(单例模式) 一、设计一个禁止拷贝的类 拷贝只会发生在两个场景中…...
探索arkui(2)--- 布局(列表)--- 2(支持分组/实现响应滚动位置)
前端开发布局是指前端开发人员宣布他们开发的新网站或应用程序正式上线的活动。在前端开发布局中,开发人员通常会展示新网站或应用程序的设计、功能和用户体验,并向公众宣传新产品的特点和优势。前端开发布局通常是前端开发领域的重要事件,吸…...
systemverilog:interface中端口方向理解
(1)从testbench的角度看,tb中信号的输入输出方向与interface中信号输入输出方向一致: (2)从DUT角度看,DUT中信号输入输出方向与interface中信号输入输出方向相反。简单图示如下: 代…...
【GUI】-- 08 JButton、JRadioButton、JCheckBox
GUI编程 03 Swing 3.5 JButton 图片置于按钮之上的JButton: package com.duo.lesson05;import javax.swing.*; import java.awt.*; import java.net.URL;public class JButtonDemo01 extends JFrame {public JButtonDemo01() {Container contentPane getConten…...
【postgresql】CentOS7 安装Pgweb
Pgweb Pgweb是PostgreSQL的一个基于web的数据库浏览器,用Go编写,可在Mac、Linux和Windows机器上运行。以零依赖性的简单二进制形式分布。非常易于使用,并具有适当数量的功能。简单的基于web和跨平台的PostgreSQL数据库浏览器。 特点 跨平台…...
基于python和定向爬虫的商品比价系统
论文下载 基于python和定向爬虫的商品比价系统 Price Comparison System for Products Based on Python and Targeted Web Crawling 目录 目录 2 摘要 3 关键词 3 第一章 绪论 4 1.1 研究背景 4 1.2 研究意义 5 1.3 国内外研究现状 7 1.4 本文主要工作和章节安排 8 …...
使用GPT-4训练数据微调GPT-3.5 RAG管道
原文:使用GPT-4训练数据微调GPT-3.5 RAG管道 - 知乎 OpenAI在2023年8月22日宣布,现在可以对GPT-3.5 Turbo进行微调了。也就是说,我们可以自定义自己的模型了。然后LlamaIndex就发布了0.8.7版本,集成了微调OpenAI gpt-3.5 turbo的…...
二十三种设计模式全面解析-深入解析模板方法模式的奇妙世界
在软件设计的奇妙宇宙中,有一种设计模式如一颗流星般划过,留下绚丽的光芒,它就是——模板方法模式(Template Method Pattern)。这个模式不仅令代码更加灵活,而且蕴含了一种设计哲学,本文将深入研…...
【Spring】加载properties文件
文章目录 在Spring Context中加载properties文件测试总结 在Spring Context中加载properties文件 分为三步,如下图所示: 完整代码: <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.…...
react中间件的理解
一、是什么? 中间件(Middleware)在计算机中,是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络应用上的各个部分或不同的应用,能…...
React函数组件状态Hook—useState《进阶-对象数组》
React函数组件状态-state 对象 state state 中可以保存任意类型的 JavaScript 值,包括对象。但是,你不应该直接修改存放在 React state 中的对象。相反,当你想要更新⼀个对象时,你需要创建⼀个新的对象(或者将其拷⻉⼀…...
linux 网络 cat /proc/net/dev 查看测试网络丢包情况
可以通过 cat /proc/net/dev 查看测试网络丢包情况,drop关键字,查看所有网卡的丢包情况 还可以看其他数据, /proc/net/下面有如下文件...
记录配置VS,使用opencv与Eigen
方法一: 1.下载VS 2.配置opencv,参考大佬博客,注意更改博客中版本的部分细节,比如opencv_world440d.lib换成自己下载的版本 3.配置Eigen,参考大佬博客 方法二:博客 本人第一次配置时候按照这篇内容配置的,但是不知道哪…...
uart控制led与beep
仲裁模块代码: // 外设控制模块,根据uart接收到的数据,控制led与beep的标志信号。 module arbit(input wire sys_clk ,input wire sys_rst_n ,input wire pi_flag …...
Linux修改root密码
如果知道当前的root密码,修改boot密码操作较简单。 步骤如下: # passwd --在root用户下执行passwd命令 Changing password for user root. New password: --此处输入新密码 BAD PASSWORD: The password is shorter than 8 characters Ret…...
C/C++模板类模板与函数模板区别,以及用法详解
类模板 类模板语法 类模板作用: 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。 语法: template<typename T> 类解释: template --- 声明创建模板 typename --- 表面其后面的…...
van-dialog弹窗异步关闭-校验表单
van-dialog弹窗异步关闭 有时候我们需要通过弹窗去处理表单数据,在原生微信小程序配合vant组件中有多种方式实现,其中UI美观度最高的就是通过van-dialog嵌套表单实现。 通常表单涉及到是否必填,在van-dialog的确认事件中直接return是无法阻止…...
Dynamic Wallpaper 16.7中文版
Macos动态壁纸推荐: Dynamic Wallpaper是一款Mac平台上的动态壁纸应用程序,它可以根据时间等因素动态切换壁纸,提供更加生动和多样化的桌面体验。 Dynamic Wallpaper包含了多个动态壁纸,用户可以根据自己的喜好选择和切换。这些…...
如何使用ArcGIS Pro制作渐变河流效果
对于面要素的河流水系,制作渐变效果方法比较简单,如果是线要素的河流有办法制作渐变效果吗,答案是肯定的,这里为大家介绍一下制作方法,希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的水系数…...
《网络协议》06. HTTP 补充 · HTTPS · SSL/TLS
title: 《网络协议》06. HTTP 补充 HTTPS SSL/TLS date: 2022-10-06 18:09:55 updated: 2023-11-15 07:53:52 categories: 学习记录:网络协议 excerpt: HTTP/1.1 协议的不足、HTTP/2、HTTP/3、HTTP 协议的安全问题、SPDY、HTTPS、SSL/TLS、OpenSSL。 comments: fa…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
