C++面向对象------继承+多态

2023-11-16

概念:

(1)继承是从已有的类创建新类的过程,这使得创建和维护一个应用程序变得更容易,达到了重用代码功能和提高执行时间的效率

(2)继承呈现了面向对象程序设计的层次结构,体现了从简单到复杂的认知过程

(3)在c++类中,如果类b继承于类a,则类a叫做基类或者父类,则b叫做派生类或者子类

语法

class 派生类名:继承方式1<基类名1>,继承方式2<基类名2>...

(语法格式:比较类似函数名后初始化的方式)

继承类型:

当一个类派生自基类,该基类可以被继承为public,protected或者private几种类型。

当使用不同类型的继承时,遵循以下几个规则:(逐渐降级)

(1)公有继承public:当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生内的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。(一般使用这种方式最多)

(2)保护继承protected:当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员

(3)私有继承private:当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员

无法被继承的成员

(1)基类的构造函数,拷贝构造函数和析构函数

(2)基类的重载运算符

(3)基类的友元函数与友元类

继承之后的成员函数的隐藏

(1)父类与子类有同名函数,子类对象调用的时候总是调用子类的函数,此时父类成员函数被隐藏(限制作用域又可以重新调回父类函数?)

(2)一般子类继承过来的函数不适合子类,或者需要扩展,则需要重新设计继承而来的父类函数

(3)函数返回值与参数可相同可不同,只需要函数名保持一致(只有virtual中考虑函数的返回值影响,其他暂时没看到函数返回值影响的内容)

(4)父类的成员函数

(5)子类的成员函数

构造函数调用顺序

构造一个子类时:(调用顺序跟函数初始化值的顺序无关)

(1)先调用父类构造函数----只跟继承填写的前后顺序有关

(2)再调用成员对象构造函数----只跟声明顺序有关

(3)最后调用自身构造函数

(记忆口诀:先父母,后兄弟,再自己)

析构函数调用顺序---与构造函数相反

继承--组合

概念:通过对现有对象进行拼接即组合,产生新的具有更复杂的功能

和继承的区别:

(1)若在逻辑关系上B是A的一种,则允许B继承A的功能。一个类可以从另一个类中派生,是另外一种类的一种

(2)若在逻辑上A是B的一部分,则不允许B继承A的功能,而要用A和其他东西组合出B,由多种类组合而成,不是派生而成

继承与多重继承

多继承:一个派生类有多个基类

多重继承:一个派生类作为其他派生类的基类

多重继承菱形问题:

 (对于此类情况也有对应的处理方式:virtual虚继承,后面此项技术需要额外补充学习)

数据冗余问题:

当D类继承于B类与C类,B类与C类有一个共同的基类时,在创建D类的对象时,A类的构造函数将会调用两次,相当于创建两个A类对象

二义性问题:

A类中成员变量,可以通过B和C去访问,此时回存在两个同种含义的变量

解决方案===使用虚继承

虚继承和动态多态的实现

多态

多态的表现

(1)现实生活中需要有相同类型,不同的情况进行对应处理。

例如:不同类型的人买票有不同的售价

(2)对于同一个行为对于不同的对象,有不同的表现,是面向对象编程三大特性之一(封装,继承,多态)

多态在c++中分为静态多态与动态多态(目前学习的技术是动态多态virtual虚函数)

(1)静态多态是基于函数重载与泛型编程实现的

(2)动态多态基于虚函数实现的(需要遵循以下规则)

必须通过基类对象的指针或引用调用函数

被调用的函数必须是虚函数,且派生类需要重写基类的虚函数

(为什么需要基类对象的指针或者引用调用函数呢。)

c++中,一般针对一个行为只会有一个名称,是对类的行为在做一个抽象

主要作用在于统一行为的接口,提高方法的通用性

静态绑定与动态绑定

区别:

(1)静态绑定指程序编译结束后就已经确定了需要调用的函数

(2)动态绑定是指在运行时才确定具体需要调用的函数

(一个是gcc编译阶段,一个是./a.out运行阶段,具体不是很理解,暂时没有具体实现过)

作用:

(1)把不同的派生类对象都当作基类对象来看,可以屏蔽不同子类对象之间的差异

(2)提高程序的通用性来适应需求的不断变化

动态多态的实现过程

实现:

(1)创建两个类,并且是继承关系

(2)基类中的函数声明称virtual函数,也就是虚函数

(3)派生类继承基类并且重写基类中的虚函数

(4)通过基类的指针或者引用访问派生类的对象

(virtual基类中填写了,子类中可以省略)

 重点:重写的特点

(1)拥有不同的作用域(分别位于派生类与基类)

(2)函数名相同,参数相同,返回值类型相同

(3)基类必须有virtual关键字,不能有static

(4)重写函数的权限访问限定符可以不同(即可以public也可以protected也可以private)

特别的---存在以下两种例外

(1)析构函数:如果不构成多态,那么指针什么类型就会调用什么类型的析构函数,这样也就会导致:如果派生类的析构函数中有资源要释放,而这里却没有释放掉那些资源,就会导致内存泄漏的问题(即析构函数可以重写:虽然函数名不同)

 

(2)协变:重写的虚函数,返回值可以不同,但是返回值必须是父,子类的指针或引用类型,即为协变(返回值不同的情况:返回值必须是父,子类的指针或引用类型,如果存在协变的情况也可以重写)

 说明符final与override

final:指定某个虚函数不能再子类中被重写,或者某个类不能被子类继承(跟函数的const关键字一样 写在最后)

在虚函数上使用:

在类上使用:

 override关键字---用来检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错(用来检查派生类虚函数是否重写正确)也和final关键字一样写在最后

 几个概念的区别:重写,重载,隐藏

重写--特点:

(1)不同的作用域(分别位于派生类与基类)

(2)函数名相同,参数相同,返回值相同

(3)基类必须要有virtual关键字,不能用static

(4)重写函数的权限访问限定符可以不同

成员函数隐藏--特点

(1)基类与派生类有同名函数,调用的时候总是调用子类的函数,此时父类成员函数被隐藏

(2)在不同的作用域内(分别位于派生类与基类)

(3)函数名相同,返回值可相同可不同

(4)参数不同时,不论有无virtual关键字,基类函数将被隐藏(注意与重载的区别:重载发生在同一作用域内)

(5)参数相同时,但基类没有virtual关键字,基类的函数被隐藏(注意与覆盖的区别:覆盖是必须要有virtual关键字)

函数重载---特点

(1)同一片作用域内

(2)函数名相同

(3)返回值可以相同可以不相同

(4)参数列表不同

重写与隐藏的区别

子类对象:子类对象在调用的时候,总是调用子类实现的成员函数

父类对象:

(1)重写:用父类的指针或引用指向子类对象的时候,覆盖的情况下,父类指针或者引用调用的函数是子类实现的函数

(2)隐藏:用父类的指针或者引用指向子类对象的时候,隐藏的情况下,父类指针或者引用的函数是父类实现的函数

多态原理与虚函数表

(和函数隐藏的this参数指针不一样,没有具体的体现形式,但是我们可以通过代码发现和体现出以下具体形式)

虚函数表:实际上对于定义了虚函数的类对象来说,有一个隐藏的虚函数表指针,指向表中存放着虚函数的地址

多态原理:由于动态绑定:因此当父类的指针或者引用去调用虚函数时,会到运行时具体的对象的虚函数表彰进行寻找对应的虚函数进行调用,若为父类类型,则调用父类虚函数,若为派生类类型,则调用派生类虚函数

代码验证实现:

父类:

 

子类

 地址打印

(1)B类存在堆区

 (2)B存在栈区

 

抽象类与纯虚函数

相关定义:含纯虚函数的类,成为抽象类

纯虚函数---指定函数接口规范,而不做的实现,实现部分由继承它的子类去实现

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++面向对象------继承+多态 的相关文章

  • 使用 LINQ to SQL 时避免连接超时的最佳实践

    我需要知道在 net 应用程序中使用 LINQ to SQL 时避免连接超时的最佳实践 特别是在返回时IQueryable
  • org.jdesktop.application 包不存在

    几天以来我一直在构建一个 Java 桌面应用程序 一切都很顺利 但是今天 当我打开Netbeans并编译文件时 出现以下编译错误 Compiling 9 source files to C Documents and Settings Ad
  • 启动时的 Excel 加载项

    我正在使用 Visual C 创建 Microsoft Excel 的加载项 当我第一次创建解决方案时 它包含一个名为 ThisAddIn Startup 的函数 我在这个函数中添加了以下代码 private void ThisAddIn
  • 打破 ReadFile() 阻塞 - 命名管道 (Windows API)

    为了简化 这是一种命名管道服务器正在等待命名管道客户端写入管道的情况 使用 WriteFile 阻塞的 Windows API 是 ReadFile 服务器已创建启用阻塞的同步管道 无重叠 I O 客户端已连接 现在服务器正在等待一些数据
  • Java中未绑定通配符泛型的用途和要点是什么?

    我不明白未绑定通配符泛型有什么用 具有上限的绑定通配符泛型 stuff for Object item stuff System out println item Since PrintStream println 可以处理所有引用类型 通
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • 当单元格内的 JComboBox 中有 ItemEvent 时,如何获取 CellRow

    我有一个 JTable 其中有一列包含 JComboBox 我有一个附加到 JComboBox 的 ItemListener 它会根据任何更改进行操作 但是 ItemListener 没有获取更改的 ComboBox 所在行的方法 当组合框
  • Keycloak - 自定义 SPI 未出现在列表中

    我为我的 keycloak 服务器制作了一个自定义 SPI 现在我必须在管理控制台上配置它 我将 SPI 添加为模块 并手动安装 因此我将其放在 module package name main 中 并包含 module xml 我还将其放
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • 如何配置eclipse以保持这种代码格式?

    以下代码来自 playframework 2 0 的示例 Display the dashboard public static Result index return ok dashboard render Project findInv
  • 如何测试 spring-security-oauth2 资源服务器安全性?

    随着 Spring Security 4 的发布改进了对测试的支持 http docs spring io spring security site docs 4 0 x reference htmlsingle test我想更新我当前的
  • 打印大型 WPF 用户控件

    我有一个巨大的数据 我想使用 WPF 打印 我发现WPF提供了一个PrintDialog PrintVisual用于打印派生的任何 WPF 控件的方法Visual class PrintVisual只会打印一页 因此我需要缩放控件以适合页面
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • java迭代器内部是如何工作的? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个员工列表 List
  • com.jcraft.jsch.JSchException:身份验证失败

    当我从本地磁盘上传文件到远程服务器时 出现这样的异常 com jcraft jsch JSchException Auth fail at org apache tools ant taskdefs optional ssh Scp exe
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • javax.persistence.Table.indexes()[Ljavax/persistence/Index 中的 NoSuchMethodError

    我有一个 Play Framework 应用程序 并且我was使用 Hibernate 4 2 5 Final 通过 Maven 依赖项管理器检索 我决定升级到 Hibernate 4 3 0 Final 成功重新编译我的应用程序并运行它

随机推荐

  • 项目启动卡在了Started Application in 10.266 seconds (JVM running for 13.033)

    好端端的项目启动后卡在这一行Started Application in 10 266 seconds JVM running for 13 033 日志中原本打印的执行的banner和程序都没有执行 访问那页面是404 很奇怪 因为啥东西
  • webpack 设置ttf 字体 不报错但是不生效

    webpack config js const path require path module exports entry src index js mode development output filename bundle js p
  • Gitee注册教程

    Gitee注册教程 目录 一 关于Gitee 二 注册Gitee 三 使用Gitee 一 关于Gitee Gitee也叫码云 是开源中国 OSChina 推出的基于Git的代码托管服务 Gitee包括三个版本 分别是 社区版 企业版和高校版
  • prometheus:(二)监控概述

    目录 一 监控系统概论 运维监控平台设计思路 二 prometheus基础资源监控 2 1网络监控 2 2存储监控 2 3服务器监控 2 4中间件监控 2 5应用程序监控 APM 三 常用监控系统介绍 3 1 Cacti 3 2 Nagio
  • tensorflow之Optimizers(tensorflow的优化器)

    一 概述 1 默认情况下 优化器训练目标函数所依赖的所有可训练变量 如果你不想训练某一个变量 你可以将关键词trainable设置为False 举例如下 global step tf Variable 0 trainable False d
  • 图像语义分割方法研究进展

    全监督学习的图像语义分割方法研究进展 简介 1 全监督学习的图像语义分割方法 1 1 基于全卷积的图像语义分割方法 1 2 基于编码器解码器结构的图像语义分割方法 1 3 基于注意力机制的图像语义分割方法 1 4 基于添加特殊模块的图像语义
  • nginx: configuration file /home/xx.local/etc/nginx/nginx.conf test failed

    nginx启动失败 输入 nginx t c HOME local etc nginx nginx conf nginx alert could not open error log file open var log nginx erro
  • 提升代码质量的几点建议

    在我从事编程工作的过程中 提升代码质量是一个极其重要且不可忽视的问题 在我看来 提升代码质量需要注意以下几点 1 遵守规范 包括变量命名规范 文件命名规范 方法命名规范等等 2 保持代码简洁 我们应该尽量避免冗余 复杂的代码 使用有意义的变
  • A - C语言实验——求一个3*3矩阵对角线元素之和

    Description 给定一个3 3的矩阵 请你求出对角线元素之和 Input 按照行优先顺序输入一个3 3矩阵 每个矩阵元素均为整数 Output 从左下角到右上角这条对角线上的元素之和 Sample Input 1 2 3 3 4 5
  • [MRCTF2020]千层套路1

    BUU题目复现 开局一个压缩包 flag全靠懵 拿到压缩包第一件事直接看能不能直接解压缩 很明显 有密码 不行 下一步 使用010Editor查看内部结构 发现确实操作着很多的 zip 文件 但是我使用binwalk foremost都没办
  • Python爬虫实战,requests模块,Python实现IMDB电影top数据可视化

    前言 利用Python爬取IMDB电影 废话不多说 让我们愉快地开始吧 开发工具 Python版本 3 6 4 相关模块 requests模块 random模块 bs4模块 以及一些Python自带的模块 环境搭建 安装Python并添加到
  • 凯恩帝对刀和刀补_KND数控车床试切对刀和调刀补

    展开全部 M 是测量的意思 有的系统是输32313133353236313431303231363533e78988e69d8331333262353363入你的测量值 然后点一个 测量 按钮 数控车对刀步骤 第一把刀的对刀步骤 第一步 确
  • linux 查询服务器的配置信息

    linux下看配置 可没有windows那么直观 你只能一个一个查看 一 cpu root srv more proc cpuinfo grep model name root srv grep model name proc cpuinf
  • 【Java数据结构】泛型详解+图文,通配符上界、下界

    0 泛型的本质 0 泛型的目的 1 泛型的语法 1 1 泛型的使用 2 包装类 2 1 装箱和拆箱 2 2 1练习题 3 泛型如何编译 4 泛型的上界 5 通配符 5 1通配符上界 5 2通配符下界 有坑填坑 0 泛型的本质 泛型的本质 泛
  • 【目标检测】25、Sparse R-CNN: End-to-End Object Detection with Learnable Proposals

    文章目录 一 背景 二 动机 三 方法 3 1 Backbone 3 2 Learnable proposal box 3 3 Learnable proposal feature 3 4 Dynamic instance interact
  • 【转载】Android Studio工程目录解析

    转载自CSDN网友HaiBing Android Studio工程目录结构分析 上 Android Studio工程目录结构分析 下 目录 Android Studio工程目录结构分析 上 Android Studio工程目录 app目录结
  • nltk_data无法下载或无法使用问题的解决方案之一

    nltk data无法下载或无法使用问题的解决方案汇总 报错展示 问题解决 本人使用的方法 1 手动下载 nltk data 数据压缩包 2 解压压缩包 找到packages文件夹 3 将packages文件夹中的文件全部复制到nltk d
  • 你是不是一个优秀的项目经理人(转)

    下面是项目管理之中最重要的一些技能被简化成的一些简单的小问题 你可以用它来测试你自己的水平 一 你没有很好地计划是因为你认为自己是一个执行者而不是计划者 很多人认为他们自己是行动型的 当他们被指派了一项任务时 他们的第一个反应就是着手开始解
  • 四、SpringBoot框架

    目录 什么是SpringBoot框架 SpringBoot的特点 作用 必会 简箱版tomcat 优缺点 面试 SpringBoot运行原理 开箱即用的全过程 SpringBoot是如何完成自动配置的 面试 SpringBoot启动项 St
  • C++面向对象------继承+多态

    概念 1 继承是从已有的类创建新类的过程 这使得创建和维护一个应用程序变得更容易 达到了重用代码功能和提高执行时间的效率 2 继承呈现了面向对象程序设计的层次结构 体现了从简单到复杂的认知过程 3 在c 类中 如果类b继承于类a 则类a叫做