C++多态概念和意义

2023-11-10

目录

一、什么叫重写

二、面向对象期望的重写

1、示例分析

2、所期望的重写

三、多态的概念和意义

1、多态的概念

2、C++如何支持多态概念

3、多态内部运行剖析

4、多态的意义

5、修改示例代码

四、静态联编和动态联编

五、小结


一、什么叫重写

1、子类中可以重定义父类中已经存在的成员函数;

2、这种重定义发生在继承中,叫做函数重写;

3、函数重写是同名覆盖的一种特殊情况。

二、面向对象期望的重写

先来验证个小示例:

#include <QCoreApplication>
#include <iostream>
#include <QDebug>

using namespace std;

class Parent
{

public:

    void Printfln()
    {
        std::cout << "Parent: void Printfln()..." << std::endl;
    }
};

class Child : public Parent
{
public:

    void Printfln()
    {
        std::cout << "Child: void Printfln()..." << std::endl;
    }
};

void run(Parent *p)
{
    p->Printfln();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Parent p;
    Child c;

    run(&p);
    run(&c);

    return a.exec();
}

1、示例分析

1、结果:结果是调用两次run函数打印的结果相同;

2、分析:

(1)编译期间,编译器只能根据指针的类型判断所指向的对象;

(2)根据赋值兼容性原则,编译器认为父类指针指向的是父类对象;

(3)run函数中的指针p,编译器不可能知道它指向的究竟是什么,但是编译器没理由报错,编译器认为最安全的做法就是调用父类Printfln()函数,因为父类和子类都有相同的Printfln()函数;

(4)因此,编译器结果只可能是调用父类定义的同名函数。

2、所期望的重写

面向对象的期望重写行为:根据实际的对象类型来判断如何调用重写函数

(1)当父类指针(引用)指向父类对象,则调用父类中定义的成员函数;

(2)当父类指针(引用)指向子类对象,则调用子类中定义的重写函数。

三、多态的概念和意义

1、多态的概念

(1)根据实际的对象类型决定函数调用的具体目标;

(2)同样的调用语句在实际运行时有多种不同的表现形态体现,这就是多态,同一语句具有多种形态。

2、C++如何支持多态概念

(1)通过使用virtual关键字对多态进行支持;

(2)被virtual修饰的函数被重写后具有多种不同的表现形态;

(3)被virtual声明的函数称为虚函数。

3、多态内部运行剖析

父类和子类的对象,首地址都各自有一个虚函数表地址,该地址都保存着虚函数Printfln()的地址,在运行过程中

(1)在父类指针(引用)p,指向父类对象,就相当于指向父类的虚函数表,从而在父类的虚函数表中找到Printfln()函数;

(2)在父类指针(引用)p,指向子类对象,相当于指向子类的虚函数表,从而在子类的虚函数表中找到Printfln()函数。

4、多态的意义

(1)在程序运行中展现出动态的特性;

(2)函数重写必须多态实现,否则没有任何意义;

(3)多态是面向对象组件化程序设计的基础特性。

5、修改示例代码

根据多态的概念,在程序中给父子类同名函数声明virtual关键字,只需要在父类中声明即可,在子类中可以不写,写了也是对的,编译器不会报错。

#include <QCoreApplication>
#include <iostream>
#include <QDebug>

using namespace std;

class Parent
{

public:

    virtual void Printfln()
    {
        std::cout << "Parent: void Printfln()..." << std::endl;
    }
};

class Child : public Parent
{
public:

    void Printfln()
    {
        std::cout << "Child: void Printfln()..." << std::endl;
    }
};

void run(Parent *p)
{
    p->Printfln();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Parent p;
    Child c;

    run(&p);
    run(&c);

    return a.exec();
}

四、静态联编和动态联编

1、静态联编:程序编译期间就能确定的具体的函数调用,如函数重载;

2、动态联编:程序运行期间才能确定的具体的函数调用,如函数重写。

五、小结

1、函数重写只能发生在父类和子类之间;

2、多态是根据实际对象类型确定调用具体的函数;

3、virtual关键字是C++支持多态的唯一方式;

4、被重写的虚函数具有多种不同表现形态。

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

C++多态概念和意义 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 如何使用 C# 中的参数将用户重定向到 paypal

    如果我有像下面这样的简单表格 我可以用它来将用户重定向到 PayPal 以完成付款
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • 12、适配器

    文章目录 package com example demo designpattern 又叫包装模式 Wrapper 各种 wrapper bridge 就是适配器模式 jbdc odbc bridge io 字节流字符流转换 角色 tar
  • STM32-ESP8266-12F与PC通信

    1 默认ESP8266的波特率是115200 2 指令及其返回值 3 使用PC的网络调试助手 协议类型选择TCP Server 端口号以80开头 表示TCP协议 如8080 8040等等 IP地址填PC的WI F网口的IP地址 配置完成后点
  • 解决浏览器设置代理IP无法上网的问题

    大家都知道 在当今信息时代 互联网已经成为了我们生活必不可少的一部分 而浏览器作为我们上网的窗口 更是被广泛使用 有时候 我们会遇到一些问题 例如设置了代理IP后无法正常上网 那么该如何解决这个问题呢 别担心 本文将为您一一解答 首先 让我
  • 易优cms:guestbookform 留言表单标签

    guestbookform 留言表单标签 基础用法 名称 guestbookform 功能 留言表单提交 语法 eyou guestbookform type default
  • 计算机组成中的阶符是什么意思,计算机中阶符,阶码,数符,尾数是什么?

    一般地 任一个二进制N 可表示为N 2j S 其中J为二进制数 叫阶码 J如果有正负号的话 正负号就叫阶符 S为纯小数 叫做尾数 数符 指的是N整个数的符号 二进制的 00101000 直接可以转换成16进制的 28 字节是电脑中的基本存储
  • 详解 Android 是如何启动的

    详解 Android 是如何启动的 2016 08 12 唐琪森 安卓开发 javascript void 0 来自 石头铺 微信号 Android Programmer 网站 www woaitqs cc 本文是 Android 系统学习
  • xilinx平台下DDR3映射为VFIFO

    FPGA开发中 数据采集 数据分析场景下需要用对高速ADC数据缓存 FPGA片内RAM无法做到大的容量 基于MIG IP做了个DDR3映射成FIFO的模块 以完成高速 量大的数据缓存应用 背景和选择 part1 官方也提供了类似功能的IP
  • makefile学习

    基本介绍 makefile编写的关键在于解决源文件的 文件依赖性 编译链接过程 源文件首先会生成中间目标文件 再由中间目标文件生成执行文件 在编译时 编译器只检测程序语法 和函数 变量是否被声明 如果函数未声明 编译器会给出一个警告 但可以
  • VS Code 打开时黑屏的恢复处理

    VS Code安装后一直黑屏的情况 一 兼容模式 Win10版本以下系统 右击VS Code打开属性窗口并在兼容性标签页内勾上以兼容模式运行这个程序 二 自动选择显卡 VS Code的渲染跟显卡设定有一定关系 打开NVIDIA控制面板 调整
  • shell脚本对硬盘进行分区——fdisk、blkid、mke2fs、mount、lsblk

    1 前言 本文介绍的是嵌入式设备烧录系统时 如何用shell脚本对硬盘进行分区 文章主要介绍的是制作烧录U盘的分区思路和关键的shell脚本语句 代码并不能直接拷贝使用 2 总体思路 1 用U盘进行系统的烧录 就是在U盘上制作一个可以运行的
  • (必备技能)使用Python实现屏幕截图

    必备技能 使用Python实现屏幕截图 文章目录 必备技能 使用Python实现屏幕截图 一 序言 二 环境配置 1 下载pyautogui包 2 下载opencv python包 3 下载PyQt5包 4 下载pypiwin32包 三 屏
  • CIFAR10数据集使用笔记

    CIFAR10数据集 1 数据集下载并转换为张量 train set torchvision datasets CIFAR10 root data path train True download True transform transf
  • JAVA语言强制类型转换要求

    JAVA语言强制类型转换要求 数据类型具有高低性的 顺序由低到高为 byte gt short gt char gt int gt long gt float gt double 1 由低到高需要强制类型转换 转换方式如下 public c
  • SIP中继对接

    freeswitch与各种设备对接的成功配置 需要的请参考 有错误的地方请指导 1 对接华为softco 中继配置 sip profiles external
  • 初探设计模式之Adapter模式

    文章目录 设计模式之Adapter模式 一 什么是Adapter模式 二 具体实例 1 使用Banner来表示高电压插座 2 使用Print来表示低电压电器 3 使用PrintBanner来表示适配器 使用的是继承 4 总体结构如下图所示
  • vivado.2019.1 安装教程

    vivado 2019 1 安装教程 下载链接 VIVADIO 2019 1 链接 https pan baidu com s 17 cPUahNzHmm 3xKsKQ7GQ 提取码 rop0 来自百度网盘超级会员V4的分享 1 解压所有文
  • JS实现随机抽奖功能

    点击开始按钮开始抽奖 div依次变红 下面是js代码 需要的自取
  • MLOps极致细节:4. MLFlow Projects 案例介绍(Gitee代码链接)

    MLOps极致细节 4 MLFlow Projects 案例介绍 Gitee代码链接 MLFlow Projects允许我们将代码及其依赖项打包为一个可以在其他平台上以可复制 reproducible 和可重用 reusable 的方式运行
  • 对称群与置换群 定义

    我刚接触抽象代数的那段时间 一直在考虑一个问题 抽象代数有什么实际应用 后来听说 群在研究一些具有对称性质的对象时有奇效 于是我试着用群去描述一些简单的几何变换 发现确实如此 这就是我在置换那篇文章的最后让大家思考等边三角形变换的原因 如果
  • C++多态概念和意义

    目录 一 什么叫重写 二 面向对象期望的重写 1 示例分析 2 所期望的重写 三 多态的概念和意义 1 多态的概念 2 C 如何支持多态概念 3 多态内部运行剖析 4 多态的意义 5 修改示例代码 四 静态联编和动态联编 五 小结 一 什么