条例18~23(设计与声明)
目录
条例18
让接口被正确使用,不易被误用
总结
条例19
设计class犹如设计type
条例20
宁以const的引用传参替代传值传参
总结
条例21
必须返回对象时,别妄想返回他的引用
总结
条例22
将成员变量声明为private
总结
条例23
宁以非友元非成员函数替换成员函数
总结
条例18
让接口被正确使用,不易被误用
- 我们不能总是指望客户正确的使用接口。接口本身的设计就应该阻止用户非法的使用接口。
- 我们可以通过让参数变成指定类型,来防止类型错误的问题。给所有参数都提供一个独有的类,让客户传参的时候通过对应类型的构造函数造出对应的对象。这样当客户试图用不同类型的参数传参的时候,编译器会发现并报错。
- 限制客户另一个错误的办法是限制类型内什么是可以做,什么是不能做。例如适当的加const.
- 同时不能过度依赖让客户做某些事,比如delete。因为客户可能不会释放或者释放两次。可以让返回的资源直接寄托给智能指针,不给客户操作的机会。同时为了防止客户对我们返回的值进行错误的析构,我们可以直接在share_ptr内绑定上指定的删除器。由于share_ptr的构造函数固定需要传指针,有的时候我们可能没有拿到原生指针,可以先用static_cast构造出智能指针,在获得了对象后再交给智能指针管理。若能直接获得对象就可以直接交给智能指针效率会更高一些。
- 使用share_ptr的另一个优点是会自动使用它的每个指针专属的删除器。这样就能消除交叉动态链接问题。这个问题是一个dll new 了一个对象却在另一个dll内被释放。但share智能指针的删除器会追踪会原来的dll.
总结
- 好的接口很容易被正常使用,不容易被误用。应该在所有接口努力达成这些性质
- 促进正确使用的办法包括接口的一致性,以及与内置行为兼容
- 阻止误用的办法包括建立新类型,限制操作,消除客户的资源管理责任,束缚对象值
- 使用share_ptr的定制删除器用来防范dll问题,还可以用来自动解除互斥锁。
条例19
设计class犹如设计type
- class设计就是type的设计。在定义一个新的type之前,要考虑之前条例的所有细节
条例20
宁以const的引用传参替代传值传参
- 通常情况下传值拷贝的效率是十分低下的,尤其在继承之后的类传值拷贝的时候,需要拷贝其父类,用引用会很大的提高效率。通过引用可以规避调用构造函数和析构函数。同时在使用引用的时候最好声明为const,否则会产生引用的对象是否会被更改的忧虑。
- 同时使用引用传参还能避免对象切割问题。当一个子类以传值拷贝的方式传递并且被视为父类的时候,就会把它当作父类而不是子类,从而调用父类的函数,这就导致了切片问题。这个问题可以通过传引用const来解决。
- 引用的底层往往通过指针来实现,若有个对象是内置类型,则可以考虑传值拷贝。以情况而定,若对象小其内含的东西大则复制拷贝十分昂贵。
- 可以假设适合传值拷贝的对象是内置类型,和stl的迭代器和函数对象
总结
- 尽量以const的引用替换传值拷贝,前者比较高效,并可避免切割问题。
- 以上规则不适用于内置类型,以及stl的迭代器和函数对象。对这些而言使用传值拷贝更加恰当。
条例21
必须返回对象时,别妄想返回他的引用
- 并不是所有函数的返回值都适合返回引用。因为引用是起别名,有的时候可能根没有可以引用返回的对象,这时若坚持使用引用就需要主动创建对象.有两种方式创建对象,在堆上或者在栈上。这又导致了新的问题,你需要调用构造函数和析构函数。并且有可能会导致返回一个已经被销毁的对象。若用static解决这个问题又会面临线程安全问题。
总结
- 绝不能返回一个指向栈上对象的指针或者引用,或者返回一个指向堆上对象的引用,或者返回一个局部静态变量。
- 该使用传值拷贝的时候不要坚持使用引用返回
条例22
将成员变量声明为private
- 若成员变量不是public,则外来客户只能通过接口访问类内成员,这样能保持接口一致性。同时通过接口获取成员变量,可以在接口内对用户加上限制条件。
- 同时使用接口意味这封装了一层,用户将对接口内的实现不知情,就算更改了内部实现,也不会影响客户的使用。将成员变量隐藏在函数接口的背后,可以为所有可能的实现提供弹性。
- 封装很重要,而使用public意味着没有封装,意味着客户代码高度依赖类的底层成员们难以更改。使用protected并不会有效解决这个问题。即使使用保护的成员变量,在派生类的眼里和共有没有什么区别。保护成员的改变会导致派生类的改变。
- 从封装的角度来看,只有两种权限,私有(封装)和其他(不封装)
总结
- 将成员变量生命为private。这可赋予客户访问数据的一致性,并细化访问权限和约束条件,并让类有充分的的弹性。
- 保护并不比公有更具有封装性。
条例23
宁以非友元非成员函数替换成员函数
- 虽然面向对象建议数据应该静可能被封装,但有的时候同样的函数在类外实现的封装性可能会好于实现成类内成员函数。
- 若你实现成类内成员函数,它还能访问类内的其他成员和函数。若你实现成类外的函数则不会增加访问的权限。要注意的两个点是,这个结论只是用于非友元,友元函数的访问大小和类内函数是一致的。另一个点是虽然他不是当前类的友元,但是不代表他不能成为另一个类的友元。
- 比较自然的做法是可以写成类外函数并跟类放在同一命名空间内。同时这样也能分离不同的功能,放在不同的头文件内,但是用同一个命名空间。用户用哪个功能就包含哪个头文件即可,这样能减少编译的代码量。std官方库的组织形式就是这种。这种写法意味着用户可以在不破坏封装性的情况下拓展相关函数。只需要在对应的命名空间下新建一个头文件即可。这点是class做不到的,哪怕是用继承,因为子类不能访问父类内的私有成员。
总结
- 宁可用非友元函数替换类内成员函数。这样做能增加封装性,弹性,和扩展性。
相关文章:
条例18~23(设计与声明)
目录 条例18 让接口被正确使用,不易被误用 总结 条例19 设计class犹如设计type 条例20 宁以const的引用传参替代传值传参 总结 条例21 必须返回对象时,别妄想返回他的引用 总结 条例22 将成员变量声明为private 总结 条例23 宁以非友元非…...

STM32 UART通信协议 基础知识
通用异步收发器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种串行、异步、全双工的通信协议。 在通信领域中,有两种数据通信方式:并行通信和串行通信。串口的数据传输是以串行方式进行的。串口在…...
nginx部署vue前端项目,访问报错500 Internal Server Error
前言 描述:当我配置好全部之后,通过 服务器 ip 地址访问,遇到报错信息:500 Internal Server Error。 情况说明 前提:我是通过Docker启动nginx容器,通过-v 绑定数据卷,将html文件和nginx.conf…...
@Excel注解
在 Java 开发中,Excel 注解通常用于标记实体类的字段,以指示与 Excel 文件的导入和导出相关的配置信息。 Excel 注解通常是自定义的注解,它可以包含多个属性,用于定义与 Excel 相关的配置,如字段的标题、顺序、数据格…...
解释器模式简介
概念: 解释器模式(Interpreter Pattern)是一种行为型设计模式,它用于定义语言的文法,并解析和执行给定语言中的表达式。该模式将每个表达式表示为一个类,并提供了一种方式来组合这些表达式以实现复杂的语句…...
图像识别技术在不同场景下有哪些应用?
图像识别技术在不同场景下的应用包括: 遥感图像识别:航空遥感和卫星遥感图像通常用图像识别技术进行加工以便提取有用的信息。该技术目前主要用于地形地质探查,森林、水利、海洋、农业等资源调查,灾害预测,环境污染监…...

阿里巴巴OceanBase介绍
前言 官网地址:https://www.oceanbase.com/ OceanBase是由蚂蚁集团完全自主研发的国产原生分布式数据库,始创于2010年。是全球唯一在 TPC-C 和 TPC-H 测试上都刷新了世界纪录的国产原生分布式数据库。 2010年,创始人阳振坤加入阿里巴巴&…...
leetcode 2560. 打家劫舍 IV
2560. 打家劫舍 IV 沿街有一排连续的房屋。每间房屋内都藏有一定的现金。现在有一位小偷计划从这些房屋中窃取现金。 由于相邻的房屋装有相互连通的防盗系统,所以小偷 不会窃取相邻的房屋 。 小偷的 窃取能力 定义为他在窃取过程中能从单间房屋中窃取的 最大金额 。…...
正点原子lwIP学习笔记——Socket接口TCP实验
1. Socket接口TCP Client配置连接 配置步骤如下所示: sin_family设置为AF_INET表示IPv4网络协议;sin_port为设置端口号;sin_addr. s_addr设置远程IP地址;调用函数Socket创建Socket连接, 注意该函数的第二个参数SOCK_…...

【Flink】
事件驱动型应用 核心目标:数据流上的有状态计算 Apache Flink是一个框架和分布式处理引擎,用于对无界或有界数据流进行有状态计算。 运行逻辑 状态 把流处理需要的额外数据保存成一个“状态”,然后针对这条数据进行处理,并且更新状态。这就是所谓的“…...

大数据Flink(九十一):Array Expansion(数组列转行)和Table Function(自定义列转行)
文章目录 Array Expansion(数组列转行)和Table Function(自定义列转行)...

华为云云耀云服务器L实例评测|华为云云耀云服务器L实例CentOS的存储和备份策略
1 华为云云耀云服务器L实例介绍 华为云云耀云服务器L实例是华为云计算服务中的一种虚拟云服务器,它提供了强大的计算资源,可以在云端运行各种应用程序和服务。 华为云服务器提供了多种实例类型,包括通用型、计算优化型、内存优化型等&#…...

Web自动化测试 —— 如何进行Selenium页面数据及元素交互?啊哈
前言: Web自动化测试是一种常用的测试方式,通过在浏览器中模拟用户操作以及与页面元素的交互,可以有效地检验页面的功能性以及稳定性。Selenium是一款流行的Web自动化测试工具,在本篇文章中,我们将介绍如何使用Seleni…...
点云从入门到精通技术详解100篇-基于全景图的室内场景点云补全方法(续)
目录 3.3 模型训练及实验评估 3.3.1 模型训练 3.3.2实验评估 4 基于自...
Debezium系列之:采集数据库数据实现对表指定的字段进行加密,下游实现对表加密后的字段进行解密
Debezium系列之:采集数据库数据实现对表指定的字段进行加密,下游实现对表加密后的字段进行解密 一、需求背景二、创建表三、深入理解加密算法的实现原理四、实现对表的指定字段加密五、插入数据六、消费Topic七、实现对加密的字段进行解密八、查看数据库一、需求背景 实际应用…...

Win10 cmd如何试用tar命令压缩和解压文件夹
环境: Win10 专业版 Microsoft Windows [版本 10.0.19041.208] 问题描述: Win10 cmd如何试用tar命令压缩和解压文件夹 C:\Users\Administrator>tar --help tar(bsdtar): manipulate archive files First option must be a mode specifier:-c Cre…...

最新AI写作系统ChatGPT源码/支持GPT4.0+GPT联网提问/支持ai绘画Midjourney+Prompt+MJ以图生图+思维导图生成
一、AI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统?小编这里写一个详细图文教程吧&#x…...
AI绘画普及课【二】图生图
文章目录 三、图生图1、图生图原理2、图生图的三个关键步骤3、参数技术性解析4、随机种子的含义研究 三、图生图 内容概要: 1、图生图原理 2、图生图基本流程 3、随机种子作用解析 1、图生图原理 图生图可以帮你把一张图片画成另一种模样。在文生图中我们看到&…...

C语言 数据类型
变量声明 格式(变量类型变量名称) 变量类型:整数类型(int),浮点数类型(float) float类型可以存储带小数的数字。 用printf()打印变量,使用%d来处理整数值,…...

瑞芯微RK3568:Debian系统如何安装Docker
本文基于HD-RK3568-IOT评估板演示Debian系统安装Docker,该方法适用于RK356X全系产品。 HD-RK3568-IOT评估板基于HD-RK3568-CORE 工业级核心板设计(双网口、双CAN、5路串口),接口丰富,适用于工业现场应用需求ÿ…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...