026 - C++ 可见性

news2024/11/20 12:19:12

本期我们讨论 C++ 的可见性。

可见性是一个属于面向对象编程的概念,它指的是类的某些成员或方法有多可见。

我说的可见性是指,谁能看见它们,谁能调用它们,谁能使用它们等这些内容。

可见性是对程序实际运行方式完全没有影响的东西,对程序性能或其他类似的东西也没有影响,它纯粹是语言层面存在的东西,目的是让你能够写出更好的代码或者帮助你组织代码。

C++ 中有三个基础的可见性修饰符,private、protected、public。

在其它语言,比如 Java 和 C# 中有其他的关键字。比如 Java,你可以不使用可见性修饰符,这就是所谓的 default 可见性修饰符;在 C# 中,有个可见性修饰符 internal。

让我们来看看 C++ 中的这三个可见性修饰符是如何工作的。

例子时间

oqyaHn.png

在一个叫做 Entity 的类中,我把 X 和 Y 定义为两个变量,因为这是一个 class,所以默认的可见性实际上是私有的(private),也就是说,这段代码和前面写上 private 是完全一样的,但是如果用的是 struct,那么它将默认是公有的(public)。

在这里没有写可见性,并不意味着它没有可见性,它其实是有的。只是它隐式的给了一个 private 可见性。

那我们就从 private 开始吧。

什么是 private?

private

private 意味着只有(only*)这个 Entity 类可以访问这些变量,它可以读取和写入它们。

上面我的描述中的 only* 带 *,因为在 C++ 中有个叫做 friend 的东西,friend 是 C++ 的关键字,它可以让类或者函数称为类 Entity 的朋友(友元)。friend 的意思就是友元,它表示可以从类中访问私有成员。

继续。

oqye4A.png

我定义了一个构造函数,把 X 赋值为 0,然后在 main 函数里面实例化这个 Entity。

当然,在这个类的作用域外是不能操作 X=2 或者类似的操作的,因为它是私有的。

我们创建一个 Entity 的子类 Player。

oqyAHr.png

Player 内部有一个构造函数,这里也是不能访问 X 的。

这个特性同样适用于函数。

如果我们创建一个函数 Print。同样的,我可以从 Entity 类中调用 Print 函数,这完全没有问题。如果我试着从 Player 中去调用它,却做不到,还是基于同样的原因。

接下来是 protected

protected

protected 比 private 更可见,比 public 更不可见。

oqyXCz.png

protected 的意思是,类 Entity 和相关层次结构中的所有子类也可以访问这些符号。

你可以看到现在 Player 类中可以写 X=2 和调用 Print 函数了。

oqyPP6.png

因为 Palyer 是 Entity 的子类,然而,我仍然不能在 main 里面这样做,因为它是完全不同的函数,且在类的外面。

最后是 public。

public

oqyLDT.png

这当然意味着所有人都可以访问。

我们可以在 Entity 类中访问它,可以在 Player 中访问它,也可以在 main 函数中访问它。

好了,这就是关于可见性的简短的回答。

现在我们谈谈为什么你要用可见性以及说明情况下要用到可见性。

为什么要用可见性

首先,我认为 public 一切是一个糟糕的想法。

对于开发者和写代码而言,这是风格问题,这是一个如何写好代码的问题。

不管是阅读代码还是扩展代码,可见性是让代码更加容易维护,更加容易理解,这与性能无关,也不会产生完全不同的代码。

可见性不是 CPU 需要理解的东西,它只是人类发明的东西,为了帮助其他人和自己。

如果你把某件事标记为 private,这基本上就是告诉看到代码的每个人,当然包括你自己,——你不应该从其他类或者其他代码中访问此内容,你只能从类的内部访问。

这意味着,如果我从来没有使用过一个类,我想看它包含了什么,我只被允许接触 public 的东西,这就是我使用这个类应该的方式,这是这个类的正确用法,——调用公共函数。

如果我使用一个类,我面对它,看到了一个我想调用的私有函数。我就明白我不应该调用私有函数,这个类的作者可能提供了一些其他的方法来实现同样的事情。

代码是个错综复杂的东西,通过明确可见性,我们可以确保人们不会调用他们不应该调用的代码,并可能破坏某些东西。

一个很好的例子是 UI 界面。

如果我想移动按钮的位置,如果我只访问按钮的坐标 X 和 Y,然后改变变量,按钮实际上可能不会移动,因为 X 轴和 Y 轴的的位置改变方式可能不同,为了让按钮真正移动,我们可能需要刷新显示。

如果我只进行了 X=5 之类的操作,X 变量是改变了,但是显示器实际上并不知道,它不知道要从内存获取新的值,而是继续使用旧的值。

然而,如果我在类中创建一个方法叫做 SetPosition 或者 SetX 之类的,我可以做的不仅仅是给 X 赋值,我还可以调用另一个叫做 Refresh 之类的方法,它能做所有它需要做的事情。

我可以让 X 变量本身为私有,然后设置那个 SetPostion 或 SetX 函数为公共函数。

显然,想要使用这些代码的人,可以看到,——哦,原来我不应该直接给 X 赋值,我应该调用 SetX 或者 SetPosition 方法。

这个例子说明了,为什么你想要使用可见性。

通常写代码的时候,你会发现,你很快忘记你写了什么东西,而且不要认为,你不会团队合作,你不需要去处理可见性,然后把所有的东西搞成 public 的。不要这样做,在几个月、几周甚至几天后,再去看你代码,你可能就已经忘记它是如何工作的了。

但是通过使用可见性这样简单的东西,你可能会看到你想要的访问和利用类的方式。

最后的话

现在人们对于可见性的争论有很多,我建议你坚持自己的想法和习惯。

有些人总是将变量写成私有的,然后搞一个公共的 getter 或者 setter ,这也是我强烈反对的一种操作。

你可以把你的想法发在评论区,本期就到这里,下期再见。

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

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

相关文章

Linux驱动开发:platform总线驱动

目录 1、为什么需要platform总线 2、设备端:platform_device 2.1 platform_device结构体 2.2 注册 2.3 注销 3、驱动端:platform_driver 3.1 platform_driver结构体 3.2 注册 3.3 注销 4、总线 4.1 bus_type 4.2 platform_bus_type 5、匹配…

2023第二届中国汽车碳中和国际峰会

会议背景 随着世界越来越认识到气候变化的破坏性影响,政府、组织和个人正在采取行动减少导致全球变暖的温室气体排放。随着电动化和互联技术的发展,汽车产业价值链正在经历变革。 汽车价值链的转型还为汽车行业创造了许多脱碳和更具可持续性的新机会。 …

vue3-admin-template页面

vue3-admin-template 本人学习视频网址为:视频地址源码:github 网页采用技术框架 本管理模板采用vue3开发,使用vue-router来作为路由跳转,将登录成功后产生的菜单,token放入到vuex中存储,通过axios来进行交互&#x…

深入理解 spring-boot-starter-parent

目录 一、前言二、Maven继承三、分析spring-boot-starter-parent四、Maven单继承问题五、不继承spring-boot-starter-parent需要注意的 一、前言 在idea当中创建springboot项目的时候都会继承一个spring-boot-starter-parent作为父类,假如不继承我们的项目就不能使…

Hudi的介绍与安装编译

Hudi的介绍 安装Maven 编译Hudi 执行编译 Hudi的介绍 Hudi简介 Hudi(Hadoop Upserts Delete and Incremental)是下一代流数据湖平台。Apache Hudi将核心仓库和数据库功能直接引入数据湖。Hudi提供了表、事务、高效的upserts/delete、高级索引、流摄取…

CentOS 7(2009) 升级 GCC 版本

1. 前言 CentOS 7 默认安装的 gcc 版本为 4.8,但是很多时候都会需要用到更高版本的 gcc 来编译源码,那么本文将会介绍如何在线升级 CentOS 的 gcc 版本。 2. 升级 GCC (1). 安装 centos-release-scl; [imaginemiraclecentos7 ~]$ sudo yum…

docker-compose搭建skywalking

SkyWalking 架构图 架构组成 SkyWalking Agent :负责从应用中,收集链路信息,发送给 SkyWalking OAP 服务器。目前支持 SkyWalking、Zikpin、Jaeger 等提供的 Tracing 数据信息。而我们目前采用的是,SkyWalking Agent 收集 SkyWalk…

测试知识总结

1.影响ui自动化稳定性 异常弹出对话框 --异常场景库 页面控件元素属性的细微变化--模糊匹配 延迟 --- retry 数据 -- 数据已被使用 2. 移动端应用细分为三大类:Web App、Native App(原生应用) 和 Hybrid App(混合应用&…

Yjs + quill:快速实现支持协同编辑的富文本编辑器

大家好,我是前端西瓜哥,这次来看看 Yjs 如何帮助我们实现协同编辑能力的。 Y.js 是一个支持 协同编辑 的开源库。只要我们将自己的数据转换为 Y.js 提供的 Y.Array、Y.Map 类型,Y.js 就会自动帮我们做数据的一致性处理和同步。 一致性问题 …

Cookie和Session的API、登录页面

目录 一、Cookie 和 Session 1、HttpServletRequest 类中的相关方法 2、HttpServletResponse 类中的相关方法 3、HttpSession 类中的相关方法 4、Cookie 类中的相关方法 二、网页登录 1、约定前后端交互接口 2、编写一个简单的登录页面 3、编写一个Servlet 来处理这个…

Springboot +Flowable,任务认领和回退(二)

一.简介 有的时候,一个任务节点会存在多个候选人,例如:张三提交一个任务,这个任务即可以由李四处理,又可以由王五处理,那么针对这种多个任务候选人的情况,该如何处理? 二.绘制流程…

SuperMap GIS基础产品组件GIS FAQ集锦(2)

SuperMap GIS基础产品组件GIS FAQ集锦(2) 【iObjects for Spark】读取GDB参数该如何填写? 【解决办法】可参考以下示例: val GDB_params new util.HashMapString, java.io.Serializable GDB_params.put(FeatureRDDProviderParam…

spi 应用层读值为0问题

昨天调SPI遇到读值为0x00&#xff0c;经排查是读写方向的问题。 #include <stdint.h> #include <stdio.h> #include <stdlib.h…

Consensus见闻:雷声大 却不下雨的奧斯汀

前言 由Coindesk举办的Consensus历时3天&#xff0c;于4月28日完美落幕&#xff0c;欧科云链研究院前往美国得克萨斯州奧斯汀参加&#xff0c;本文将分享我们在奧斯汀和Consensus会议中的所见所闻&#xff0c;带你们看一个不一样的奧斯汀。 出品&#xff5c;欧科云链研究院 作…

datagrip连接elasticsearch且进行查询20230506

背景&#xff1a;公司要做一个es的数据存储&#xff0c;然后通过接口进行查询&#xff0c;我在docker下完成了ELK的安装&#xff0c;但是对es还不是很了解&#xff0c;就想着用logstash加载完数据到es中后&#xff0c;在数据库中对es进行查询&#xff0c;发现datagrip是支持连接…

Boosting之Adaboost与GBDT

同质与异质 1.异质模型&#xff1a;把不同类型的算法集成在一起&#xff0c;基础模型要有足够大差异性&#xff08;可以找出最适合当前数据的模型&#xff09; 同质模型&#xff1a;通过一个基础算法生成的同类型学习器。 Boosting概念介绍 Boosting本意就是提升&#xff0…

腾讯云服务器怎么开通端口?以80端口为例轻量和CVM教程合集

腾讯云服务器怎么放通80端口&#xff1f;腾讯云服务器分为云服务器CVM和轻量应用服务器&#xff0c;CVM云服务器在安全组中配置规则开启80端口&#xff0c;轻量应用服务器在防火墙中开通80端口&#xff0c;阿腾云来详细详细说下腾讯云服务器开通80端口教程&#xff1a; 目录 …

【c语言】字符串拼接 | API仿真

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ …

linux usb gadget driver代码

本文基于linux-5.4.124 aspeed 2600(BMC)的代码实现来描述arm结构下的gadget driver. 在读之前&#xff0c;我们需要了解什么是usb gadget driver&#xff0c;以及它的作用。 从英文字面上翻译看&#xff0c;usb gadget driver是一个usb小工具驱动。这说了等于没说。实际上&a…

如何通过代码接入手机在网状态 API

引言 在许多场景下&#xff0c;手机号码是一种常用的身份验证信息。而使用手机在网状态 API 可以判断出手机号码是否有效&#xff0c;在一定程度上提高了身份验证的准确性和安全性&#xff0c;它的出现和广泛应用&#xff0c;为各行各业提供了更为便利和高效的解决方案。 本文…