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

C++语法规则3(C++面向对象)

多态

C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数;

形成多态必须具备三个条件:

  1. 必须存在继承关系;
  2. 继承关系必须有同名虚函数(其中虚函数是在基类中使用关键字 virtual 声明的函数,在派
    生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数);
  3. 存在基类类型的指针或者引用,通过该指针或引用调用虚函数。

这里我们还需要理解两个概念:

虚函数:

是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,
会告诉编译器不要静态链接到该函数。我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。虚函数声明如下:virtual
ReturnType FunctionName(Parameter) 虚函数必须实现,如果不实现,编译器将报错

纯虚函数:

若在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基
类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。纯虚函数声明如下:
virtual void funtion1()=0; 纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。

包含纯虚函数的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。

上面那些概念大家可以捋一捋,毕竟 C++概念还是挺多的。为什么说到多态要与虚函数和
纯虚函数扯上关系?光说概念没有实例确实难理解。下面我们还是以我们熟悉的狗类和动物类,另外加一个猫类进行多态的讲解。

新建一个目录 09_polymorphism_example,编辑一个 09_polymorphism_example.cpp 内容如下。(PS: polymorphism 翻译多态的意思,笔者就以这种方式命名例程了)。

1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 /* 定义一个动物类 */ 6 class Animal 7 { 8 public: 9 virtual void run() { 10 cout<<"Animal 的 run()方法"<<endl; 11 } 12 }; 13 14 /* 定义一个狗类,并继承动物类 */ 15 class Dog : public Animal 16 { 17 public: 18 void run() { 19 cout<<"Dog 的 run()方法"<<endl; 20 } 21 22 }; 23 24 /* 定义一个猫类,并继承动物类 */ 25 class Cat : public Animal 26 { 27 public: 28 void run() { 29 cout<<"Cat 的 run()方法"<<endl; 30 } 31 32 }; 33 34 int main() 35 { 36 /* 声明一个 Animal 的指针对象,注:并没有实例化 */ 37 Animal *animal; 38 /* 实例化 dog 对象 */ 39 Dog dog; 40 /* 实例化 cat 对象 */ 
41 Cat cat; 42 43 /* 存储 dog 对象的地址 */ 44 animal = &dog; 45 /* 调用 run()方法 */ 46 animal->run(); 47 48 /* 存储 cat 对象的地址 */ 49 animal = &cat; 50 /* 调用 run()方法 */ 51 animal->run(); 52 return 0; 53 } 

第 9 行、第 18 行和第 28 行,都有一个 run()方法。其中我们可以看到基类 Animal 类的 run()方法前面加了关键字 virtual。这样让基类 Animal 类的 run()方法变成了虚函数。在这个例子里我们可以知道虚函数是 C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。简单的来说,上面的实例是基类 Animal 声明了一个指针 animal。
然后通过基类的指针来访问 Dog 类对象与 Cat 类的对象的 run()方法,前提是基类的 run()方法必须声明为虚函数,如果不声明为虚函数,基类的指针将访问到基类自己的 run()方法。我们可以尝试把 virtual 关键字去掉再重新编译测试,如果不加关键字 virtual 会是什么情况。

第 44 行和第 49 行,可以理解是 animal 指针实例化的过程。当基类的 run()方法定义成虚函
数,编译器不静态链接到该函数,它将链接到派生类的 run()方法,进行实例化。
执行下面的指令编译。

g++ 09_polymorphism_example.cpp -o 09_polymorphism_example 

编译完成执行的结果如下。
在这里插入图片描述

数据封装

封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受
到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。

数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴
露接口而把具体的实现细节隐藏起来的机制,C++ 通过创建类来支持封装和数据隐藏(public、protected、private)。

其实我们在第 2.2 小节开始就已经接触了数据封装。在 C++程序中,任何带有公有和私有
成员的类都可以作为数据封装和数据抽象的实例。通常情况下,我们都会设置类成员状态为私有(private),除非我们真的需要将其暴露,这样才能保证良好的封装性。这通常应用于数据成员,但它同样适用于所有成员,包括虚函数。

下面我们还是以狗类为例,增加一个食物的方法 addFood(int number)。将获得食物的方法
设定在 public 下,这样 addFood(int number)方法就暴露出来了,也就是对外的接口。然后我们设置狗类的私有成员(private)食物的份数 total。我们在这个教程里第一次使用 private,在这章节里我们也可以学到什么时候该使用 private 什么时候使用 public。total 为获得的食物总数,然后我们还写一个公开的方法 getFood()在 public 下,通过 getFood()来打印出小狗总共获得了几份食物。

新建一个目录 10_encapsulation_example,编辑一个 10_encapsulation_example.cpp 内容如下。
(PS: encapsulation 翻译封装的意思,笔者就以这种方式命名例程了)。

1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Dog 6 { 7 public: 8 string name; 9 10 Dog(int i = 0) 11 { 12 total = i; 13 } 14 15 void addFood(int number) { 16 total = total + number; 17 } 18 19 int getFood() { 20 return total; 21 } 22 private: 23 int total; 24 }; 25 26 27 int main() 28 { 29 Dog dog; 30 31 dog.name = "旺财"; 32 33 dog.addFood(3); 34 dog.addFood(2); 35 36 cout<<dog.name<<"总共获得了"<<dog.getFood()<<"份食物"<<endl; 37 38 return 0; 39 } 

第 10 至第 13 行,在构造函数里初始化 total 的数量,不初始化 total 的数量默认是随 int 类
型的数。所以我们需要在构造函数里初始化,也体现了构造函数的功能,一般是在构造函数里初始化。不要在类内直接赋值初始化,有可能有些编译器不支持。

第 15 至 17 行,addFood(int number),在这个方法里,将获得的食物份数赋值给 total。

第 19 至 21,getFood(),在这个方法里,将返回食物的总份数。通过调用这个方法,即可
访问私有成员的 total 总数。

第 33 和 34 行,添加食物的份数。

第 36 行,打印食物的总份数。
执行下面的指令编译。

g++ 10_encapsulation_example.cpp -o 10_encapsulation_example 

编译完成执行的结果如下。
在这里插入图片描述

数据抽象

数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息
而不呈现细节。数据抽象是一种依赖于接口和实现分离的编程(设计)技术。

数据抽象的好处

  1. 类的内部受到保护,不会因无意的用户级错误导致对象状态受损。
  2. 类实现可能随着时间的推移而发生变化,以便应对不断变化的需求,或者应对那些要
    求不改变用户级代码的错误报告。

举个简单的例子,比如我们生活中的手机。手机可以拍照、听音乐、收音等等。这些都是
手机上的功能,用户可以直接使用。但是拍照的功能是如何实现的,是怎么通过摄像头取像然后怎么在屏幕上显示的过程,作为用户是不需要知道的。也就是暴露的不用太彻底,用户也不必须知道这种功能是如何实现的,只需要知道如何拍照即可。

就 C++ 编程而言,C++ 类为数据抽象提供了可能。它们向外界提供了大量用于操作对象
数据的公共方法,也就是说,外界实际上并不清楚类的内部实现。

其实像 cout 这个对象就是一个公共的接口,我们不必要知道 cout 是如何在屏幕上显示内容
的。cout 已经在底层实现好了。

在上一节我们已经学习过数据封装,数据封装是一种把数据和操作数据的函数捆绑在一起
的机制,而数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。

C++ 程序中,任何带有公有和私有成员的类都可以作为数据抽象的实例。例子略,例子可
参考上 2.2.5 小节的例子。

相关文章:

C++语法规则3(C++面向对象)

多态 C多态意味着调用成员函数时&#xff0c;会根据调用函数的对象的类型来执行不同的函数&#xff1b; 形成多态必须具备三个条件&#xff1a; 必须存在继承关系&#xff1b;继承关系必须有同名虚函数&#xff08;其中虚函数是在基类中使用关键字 virtual 声明的函数&#…...

Python tkinter 如何实现网站下载工具?将所有数据一键获取

前言 铁汁们有没有想过&#xff0c;如何把几个代码的功能结合到一起呢&#xff1f; 有想过的话&#xff0c;有没有实现过呢&#xff1f; 其实很简单的啊&#xff0c;咱就写一个界面就好了&#xff0c;想要哪个代码运行&#xff0c;鼠标轻轻一点就行 开发环境 python 3.8: 解…...

第六章:C语言数据结构与算法初阶之栈

系列文章目录 文章目录系列文章目录前言一、栈二、栈的实现三、接口函数的实现1、初始化2、销毁栈3、压栈与出栈4、判空5、元素个数6、返回栈顶元素四、栈中元素的访问总结前言 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 一、…...

Android学习之WebView

什么是WebView WebView是Android中UI组件的一种&#xff0c;WebView基于webkit内核&#xff0c;不过由于兼容性的原因在Android5.0后改为了Chromium内核。 WebView可以用来展示网页&#xff0c;常用于我们不想打开浏览器但又想浏览网页的情况。 WebView的使用 WebVeiw的常用…...

3/11 考试总结

时间安排 7:30–7:50 读题&#xff0c;T1 是个利用随机性的题目&#xff0c;T2 dp,T3 不知道是啥。 7:50–8:30 T1,对于随机有个结论时最值突变不超过 log &#xff0c;于是可以处理出所有 log 个区间然后统计答案&#xff0c;但这暴力做是个 3log 铁定过不去。 8:30–8:50 T2…...

Leetcode 141.环形链表 142环形链表II

141环形链表 文章目录快慢指针快慢指针 代码思路&#xff1a; slow 和fast 指向 head slow走一步&#xff0c;fast走两步 没有环&#xff1a; fast每次走2步 &#xff0c;如果 fast 最终遇到NULL(链表中的元素是 偶数)或者fast->next(链表中的元素是 奇数)遇到NULL&#xf…...

hibernate学习(五)

hibernate学习&#xff08;五&#xff09; hibernate的一对多关联映射&#xff1a; 一、数据库表与表之间关系 一对多建表原则&#xff1a; 多对多的建表原则&#xff1a; 一对一建表原则&#xff1a; &#xff08;1&#xff09;唯一外键对应&#xff1a; &#xff08;…...

STM32CubeIDE 快速开发入门指南

描述 STM32CubeIDE是一体式多操作系统开发工具&#xff0c;是STM32Cube软件生态系统的一部分。 STM32CubeIDE是一种高级C/C开发平台&#xff0c;具有STM32微控制器和微处理器的外设配置、代码生成、代码编译和调试功能。它基于Eclipse/CDT™框架和用于开发的GCC工具链&#xf…...

华为OD机试 - 火星文计算(C 语言解题)【独家】

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 使用说明本期题目:火星文计…...

超超超超保姆式详解——字符函数和字符串函数(学不会打我)上

目录 长度不受限制的字符串函数 strlen部分 strlen函数的易错小知识 strlen函数的实现 strcpy部分 strcat部分 自己实现strcat strstr函数部分 简单例子&#xff1a; 分析 strcmp部分 长度受限制的字符串函数 strncpy 简单例子 strncat strncmp 简单例子 &…...

Data mesh 笔记

有用的网站 https://www.datamesh-architecture.com/ https://www.agilelab.it/data-mesh-in-action https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/scenarios/cloud-scale-analytics/well-architected-framework https://www.datamesh-architecture.com…...

(八十三)大白话透彻研究通过explain命令得到的SQL执行计划(2)

今天我们就一步一步的来讲解不同的SQL语句的执行计划长什么样子&#xff0c;先来看第一条SQL语句&#xff0c;特别的简单&#xff0c;就是&#xff1a; explain select * from t1 就这么一个简单的SQL语句&#xff0c;那么假设他这个里面有大概几千条数据&#xff0c;此时执行计…...

案例18-面向对象之开门小例子

目录 一&#xff1a;背景介绍 二&#xff1a;思路&方案 1.面向过程 2.面向对象 3.面向对象(反射) 三&#xff1a;过程 1.面向过程&#xff1a;原本何老师的作用交给我了米老师来完成。 2.面向对象&#xff1a;把开门的方法完全交个何老师&#xff0c;米老师不需要有…...

【碎片化知识总结】三月第一周

目录 前言 1、开发中常用的 IDEA 编辑器&#xff0c;如何做到不用每次都重新配置&#xff1f; 2、如何使用 Python 获取视频文件信息&#xff1f; 3、使用 Java 的 try-with-resources 优化代码 4、使用 shell 脚本批量修改服务器某一目录下的文件后缀名称 5、MySQL优化&…...

从零开始的JSON库(1):启程

1. JSON 是什么 JSON&#xff08;JavaScript Object Notation&#xff09;是一个用于数据交换的文本格式&#xff0c;现时的标准为ECMA-404 。 虽然 JSON 源自于 JavaScript 语言&#xff0c;但它只是一种数据格式&#xff0c;可用于任何编程语言。现时具有类似功能的格式有X…...

【Java】数组

目录 1.数组的定义与初始化 2.遍历数组 3.认识null 4.引用变量 5.返回多个值 6.数组拷贝 7.数组逆序 8.数组填充 9.小练习 //将整形数组转化为字符串 //二分查找优化 //冒泡排序优化 10.二维数组 //遍历二维数组 //不规则的二维数组 1.数组的定义与初始化 int…...

【C++】非类型的模板参数,特化

目录 1.类型模板参数和非类型模板参数 2.特化 3. 模板的分离编译 4.模板的优缺点 1.类型模板参数和非类型模板参数 之前写模板传的都是类型——类型模板参数 现在想定义两个静态数组&#xff0c;数组长度不同&#xff0c;就可以用模板参数传数值而不是传类型 非类型模板…...

核方法(kernel Method)

核方法 核方法定义 一种能够将在原始数据空间中的非线性数据映射到高维线性可分的方法。 核方法的用处 1、低维数据非线性&#xff0c;当其映射到高维空间&#xff08;feature space&#xff09;时&#xff0c;可以用线性方法对数据进行处理。 2、线性学习器相对于非线性学…...

消息队列MQ用来做什么的,市场上主流的四大MQ如何选择?RabbitMQ带你HelloWorld!

文章目录MQ用来做什么的MQ会有什么样的麻烦MQ消息队列模式分类MQ消息队列常用协议市场主流四大MQRabbitMQ项目开发RabbitMQ中的组成部分MQ用来做什么的 省流 &#xff1a;系统解耦、异步调用、流量削峰 系统解耦 首先举例下面这个场景&#xff0c;现有ABCDE五个系统&#xff…...

2023年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛(同步赛) A — E

2023年中国高校计算机大赛-团队程序设计天梯赛&#xff08;GPLT&#xff09;上海理工大学校内选拔赛&#xff08;同步赛) 文章目录A -- A Xor B Problem题目分析codeB -- 吃苹果题目分析codeC -- n皇后问题题目分析codeD -- 分苹果题目分析codeE -- 完型填空题目分析codeA – A…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...