多态原理探究

2023-11-15

概念

  1. 当类中声明虚函数时,编译器会在类中生成一个虚函数表
  2. 虚函数表是一个存储类成员函数指针的数据结构
  3. 虚函数表是由编译器自动生成与维护的
  4. virtual成员函数会被编译器放入虚函数表中
  5. 当存在虚函数时,每个对象中都有一个指向虚函数表的指针(C++编译器给父类对象、子类对象提前布局vptr指针;当进行howToPrint(Parent *base)函数是,C++编译器不需要区分子类对象或者父类对象,只需要再base指针中,找vptr指针即可。)
  6. VPTR一般作为类对象的第一个成员

实现原理

  • C++中多态的实现原理
  • 当类中声明虚函数时,编译器会在类中生成一个虚函数表
  • 虚函数表是一个存储类成员函数指针的数据结构
  • 虚函数表是由编译器自动生成与维护的
  • virtual成员函数会被编译器放入虚函数表中
  • 存在虚函数时,每个对象中都有一个指向虚函数表的指针(vptr指针)

  • 通过虚函数表指针vptr调用函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正调用的函数,普通成员函数在编译时就确定调用的函数,所以效率上虚函数要比普通函数的开销大很多
  • 同样的,虚函数的开销又要比平常的大,因为在声明了virtual会有一个指针的开销
  • C++编译器,执行HowToPrint函数,不需要区分是子类对象还是父类对象
构造函数中能调用虚函数,实现多态吗

首先说结论,不能,这其实是vptr指针的初始化问题
整体来说:只有在对象构造完全结束,后vptr指针才最终的指向确定
父类的vptr指针会指向父类虚构函数表
子类的vptr指针会指向子类虚构函数表
如果细分的话
他其实是分步的,当创建一个子类对象的时候,vptr指针会先指向父类的虚构函数表,在父类完成构造后,会才会指向子类的虚构函数表在这里插入图片描述

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

多态原理探究 的相关文章

  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 重载<<的返回值

    include
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 如何将带有 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我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • 近年来,学习图像去雾不得不看的论文和源代码

    S G Narasimhan and S K Nayar 多幅图像 同一场景不同时间 天气 去雾 主页 NASA Retinex理论增强 主页 Ana Bel n Petro总结了NASA的Retinex理论 源代码 不过不是matlab版
  • HDU--1050:Moving Tables (贪心)

    1 题目源地址 http acm hdu edu cn showproblem php pid 1050 2 解题思路 将每个输入的起始房间和结束房间转换为房间前面的区间 按区间起始位置从小到大排序 首先取第一个区间 后续如果有区间的起始位
  • 计算机网络-第一章 计算机网络体系结构(详细知识点总结)

    目录 第一章 计算机网络体系结构 大纲 1 1 计算机网络概述 1 1 1 计算机网络的概念 1 1 2 计算机网络的组成 1 1 3 计算机网络的功能 1 1 4 计算机网络的分类 1 1 5 计算机网路的标准化工作及相关组织 1 1 6
  • 编译mediastreamer2/ffmpeg/linphone(x86平台)

    在x86环境下编译mediastreamer2的步骤 1 编译OGG库 音频编解码 http www xiph org downloads configure prefix usr disable static 2 编译SPEEX 音频编解
  • java对象比较器_具有多个字段的对象的Java比较器

    我有Collection5个字段的对象 id entityType entityId brandId productId 要排序的ArrayList的Collection我写了下面Comparaor Comparator collectio
  • uint是什么数据类型_「IEC 61131-3」标准数据类型

    IEC 61131 3定义的标准数据类型有 布尔型 整型 浮点型 字符串型 时间日期类型和常数 以下将逐一介绍各种数据类型 布尔型 布尔变量可取值TRUE和FALSE 占8位内存空间 布尔型变量声明示例 bExec BOOL FALSE b
  • 无法启动此程序,因为计算机中丢失QT5Core.dll

    背景 QT项目从QTCreator移植到VS2010中时出现这个问题 原因 在Qt Creator中运行时会根据你当前选择的构建套件生成一套自己的环境变量 这套环境变量与当前电脑的环境变量的差别是添加了Qt库的引用路径 所以在Creator
  • 取余运算的规则

    取余运算满足以下规则 x y p x p y p p 证明如下 假设 x a p b y c p d 则 x p b y p d 则 x y p a p b c p d p a c p b d p b d p x p y p p
  • JAVASE总复习

    一 填空题 共 20 个题目 总计 20 分 1 Java application 中的主类需要包含 main 方法 main 方法的返回类型是void 2 移位运算符可以起到对操作数乘以 2 或者除以 2 的作用 那么操作数除以 2 的移
  • shader练习中遇到的问题点

    half3 lrDirWS normalize reflect lDirWS nDirWS 不加normalize会有白点点 1 max 0 ndotv 模型上会出现黑点点 max 0 1 ndotv 模型上不会出现黑点点
  • Spirng的事务 方法A调用方法B,事务是否失效

    Springboot开启了事务的方法调用没有事务的方法 提示 上方标题是一个很笼统的场景 详情展开如下 先说结论 总结 方法A调用方法B 场景一 如果A和B方法在同一个类中 如果A加 Transactional注解 B加不加 Transac
  • 看完这篇 教你玩转渗透测试靶机vulnhub——FunBox1

    Vulnhub靶机FunBox1渗透测试详解 Vulnhub靶机介绍 Vulnhub靶机下载 Vulnhub靶机安装 Vulnhub靶机漏洞详解 信息收集 暴力破解 ssh登入 提权 获取flag Vulnhub靶机渗透总结 Vulnhub
  • Golang CLI框架介绍

    网址 https github com mitchellh cli 功能 该框架是个人开发的命令行程序框架 作者还成立了公司 HashiCorp 其公司的产品也采用这个CLI框架 解读 框架的思路是 把命令和执行方法以map的形式记录在内部
  • 命令查看被占用端口号,并杀死进程

    1 win R 输入cmd回车打开命令窗口 2 查看所有端口 命令 netstat an 3 查看单个端口号是否被占用 netstat ano findstr 8080 最后一列是占用端口对应的进程号 4 查看进程号对应的进程名称 task
  • 关于对比损失(contrasive loss)的理解(相似度越大越相似的情况):

    def contro loss self 总结下来对比损失的特点 首先看标签 然后标签为1是正对 负对部分损失为0 最小化总损失就是最小化类内损失 within loss 部分 让s逼近margin的过程 是个增大的过程 标签为0是负对 正
  • gitee的一些常用命令

    Gitee 是一个基于 Git 的代码托管和协作平台 提供了一些常用的命令来完成代码的管理和协作 以下是一些常见的 Gitee 命令 克隆远程仓库到本地 Copy Codegit clone lt 远程仓库地址 gt 将本地代码提交到远程仓
  • Matlab

    目录 摘要 一 电力负荷数据导入 二 输入输出数据归一化 三 建立和训练BP神经网络 四 使用测试数据进行负荷预测 五 Matlab代码实现 摘要 使用BP神经网络实现简单的电力负荷回归预测任务 主要的步骤为 导入数据 数据归一化 建立BP
  • Linux中级实战专题篇三:nginx服务(日志介绍,作用域,格式定义,流量控制,访问控制模块,用户信任登录)

    Nginx 日志配置 1 Nginx 日志介绍 Nginx 有一个非常灵活的日志记录模式 每个级别的配置可以有各自独立的访问日志 所需日志模块 ngx http log module 的支持 日志格式通过 log format 命令来定义
  • NP完全问题的证明-算法概论课后习题8.15

    题目 证明如下问题是NP 完全的 输入 两个图G1 V1 E1 和G2 V2 E2 预算b 输出 两个节点集合V1 V1 和V2 V2和它们被移除后 将在两图中分别留下至少b个节点 且图的剩余部分完全一样 解析 可将最大独立集问题归约到此问
  • 多态原理探究

    概念 当类中声明虚函数时 编译器会在类中生成一个虚函数表 虚函数表是一个存储类成员函数指针的数据结构 虚函数表是由编译器自动生成与维护的 virtual成员函数会被编译器放入虚函数表中 当存在虚函数时 每个对象中都有一个指向虚函数表的指针