条例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路串口),接口丰富,适用于工业现场应用需求ÿ…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
