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

条例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来处理整数值&#xff0c…...

瑞芯微RK3568:Debian系统如何安装Docker

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

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...