c++虚函数详解(多态特性)

news2024/11/24 16:42:54

1.c++多态的概念

多态是c++的特征之一

多态的分类:静态多态(静态联编)、动态多态(动态联编)

静态多态(静态联编):函数入口地址 是在 编译阶段 确定(运算符重载、函数重载)

动态多态(动态联编):函数入口地址 是在 运行阶段 确定(虚函数)

2.什么是向上类型转换

即:定义一个父类引用指针指向子类对象,通过父类指针或 引用来操作子类对象

示例代码如下:

#include <iostream>
using namespace std;

class Animal
{
public:
    void sleep(void)
    {
        cout<<"animal 动物在睡觉"<<endl;
    }
};

class Cat:public Animal
{
public:
    void sleep(void)
    {
        cout<<"Cat 猫在睡觉!! 喵喵"<<endl;
    }
};
int main()
{
    //用基类(指针或引用) 保存 子类对象(向上转换)
    Animal *p = new Cat;
    p‐>sleep();//调用的是基类的sleep

    Cat cat;
    Animal &ob = cat;
    ob.sleep();//调用的是基类的sleep
    return 0;
}

可见两次都是打印的基类中的sleep函数,而不是子类中的sleep函数。

 上图也解释了为什么只能打印基类中的sleep函数,因为这个基类指针(引用)只能操作Cat中的基类部分,而不能访问到Cat部分。

3.想用基类指针(引用)访问子类对象中的成员 要使用虚函数

虚函数允许子类重新定义父类中的成员函数,这种方法称为覆盖。即在父类中声明这个函数的时候

使用virtual关键字修饰。

如果一个函数在基类中被声明为 virtual,那么在所有派生类中它都是 virtual 的.

#include <iostream>

using namespace std;
class Animal
{
public:
    //虚函数 本质 是一个函数指针变量
    virtual void sleep(void)
    {
        cout<<"animal 动物在睡觉"<<endl;
    }
};
class Cat:public Animal
{
public:
    virtual void sleep(void)
    {
        cout<<"猫在睡觉!!喵喵"<<endl;
    }
};
int main()
{
    Animal *p = new Cat;
    p‐>sleep();//调用的是cat中sleep
    return 0;
}

 这样就能访问父类中的sleep函数。原因如下:

当一个基类中有虚函数时,里面会产生虚指针,同时会产生一个虚函数表

没有涉及到继承的时候,虚函数表里面存储的就是当前类里的虚函数入口地址;

当涉及到继承时,子类会继承父类中的虚指针和虚函数表编译器会自动将子类中的虚函数放入虚函数表中,于是这个虚指针遍历虚函数表时,拿到的就是子类中的虚函数地址;

上图中定义了基类指针 Animal *p = new Cat,然后p‐>sleep()调用函数,此时p的访问也是没有越界的,访问的仍然是Cat中的基类部分,只不过此时虚函数表中保存的是子类sleep函数地址,所以访问的是子类sleep函数。

  • :C++的动态捆绑机制是怎么样的?

首先,我们看看编译器如何处理虚函数。 当编译器发现我们的类中有虚函数的时候,编译器会

创建一张虚函数表,把虚函数 的函数入口地址放到虚函数表中,并在类中秘密增加一个虚指针,

这个指针就是 vpointer(缩写 vptr),这个指针是指向对象的虚函数表。在多态调用的时候,根据 

vptr指针,找到虚函数表来实现动态绑定。

4.虚函数的应用案例(基类指针、引用 作为函数的参数)

 示例代码:

#include <iostream>

using namespace std;
class Base
{
public:
    //虚函数 本质 是一个函数指针变量
    virtual void sleep()
    {
        cout<<"父亲在睡觉"<<endl;
    }
};
class Son1:public Base
{
public:
    void sleep()
    {
        cout<<"Son1在安静睡觉"<<endl;
    }
};
class Son2:public Base
{
public:
    void sleep()
    {
        cout<<"Son2在轻度睡觉"<<endl;
    }
};
class Son3:public Base
{
public:
    void sleep()
    {
        cout<<"Son3在雨声睡觉"<<endl;
    }
};
class Son4:public Base
{
public:
    void sleep()
    {
        cout<<"Son4在鼾声如雷睡觉"<<endl;
    }
};
//以基类指针作为函数参数 函数就可以操作所有子类
void sleepFun(Base &ob)
{
    ob.sleep();
}

int main(int argc, char *argv[])
{
    Son1 ob1;    //初始化子类对象
    Son2 ob2;
    Son3 ob3;
    Son4 ob4;
    sleepFun(ob1);
    sleepFun(ob2);
    sleepFun(ob3);
    sleepFun(ob4);
    return 0;
}

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

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

相关文章

微信小程序自定义tabBar

1.app.json中tabBar里设置 "custom":true 设置好后就可使用自定义tabBar。 注意&#xff1a;list中的页面必须保存&#xff0c;且必须和自定义的tabBar页面数据一致 "tabBar": {"custom": true,"list": [{"pagePath": &q…

基于springboot篮球论坛系统

开发技术介绍 B/S架构 随着软件系统的不断改进和升级&#xff0c;B/S结构产品更为方便的特征体现地十分明显。对于一个中等偏大的公司来说&#xff0c;如果系统管理员每天要在很多台电脑之间来回查看&#xff0c;不断奔走&#xff0c;那么效率和工作量就会变得很低&#xff0…

【Redis】Redis实现点赞、点赞排行榜

目录 一、点赞 1、思路 2、代码实现 二、点赞排行榜 1、思路 2、代码实现 一、点赞 1、思路 在我们的项目中我们有时候会碰到这样的需求&#xff0c;比如实现一个博客系统&#xff0c;当用户访问到这篇博客时可以进行点赞&#xff0c;那么这个功能如何去实现呢&#xff…

Midjourney|文心一格 Prompt:完整参数列表、风格汇总、文生图词典合集

Midjourney|文心一格 Prompt&#xff1a;完整参数列表、风格汇总、文生图词典合集 1.Midjourney 完整参数列表 参数名称 调用方法使用案例注意事项V5V4V3niji版本在关键词后加空格&#xff0c;然后带上版本参数&#xff1a; --v 或者 —v –version 或者 —versionvibrant cali…

【密码学复习】第八讲 数字签名

数字签名&#xff08;Digital Signature&#xff09;&#xff0c;也称电子签名&#xff0c;是指附加在某一电子文档中的一组特定的符号或代码&#xff0c;它是利用数学方法对该电子文档进行关键信息提取并与用户私有信息进行混合运算而形成的&#xff0c;用于标识签发者的身份以…

SpringBoot学习之集成Swagger3(二十七)

一、Maven配置 注意swagger的版本号是3.0.0版本以上才可以,这里我们就选择3.0.0版本 完整的Maven配置如下(仅供参考): <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaL…

vulnhub渗透测试靶场练习1

靶场介绍 靶场名&#xff1a;Medium_socialnetwork 下载地址&#xff1a;https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 环境搭建 靶机建议选择VM VirtualBox,我一开始尝试使用VMware时会报错&#xff0c;所以改用VM VirtualBox&#xff0c;攻击机使用…

魔改车钥匙实现远程控车:(前传)在macOS上安装使用Arduino

前言 因为最近有个需求需要硬件支持&#xff0c;原本打算使用 Arduino Nano&#xff0c;后来在 Boot 大佬的建议下&#xff0c;买了某宇宙家的 ESP32C3 核心板&#xff0c;对比 Arduino Nano 价格便宜了一大半&#xff0c;而且自身就集成了 WIFI 和 BLE 模块&#xff0c;还不用…

(一)before initialization of D3D(初始化D3D之前你需要了解的D3D基础知识)

什么是D3D? D3D全称Direct X 3D,即一组API可以用来针对GPU编程,不过他最主要的作用是用来渲染(不过现在也有很多其他应用比如d3d11va[Direct X 3D 11 Video API]用来进行硬件加速解码) Tips:Direct X 3D主要用来渲染,既然我们说到可以针对GPU编程了,当然不只是渲染的工作可以…

国考省考行测:数量关系,牛吃草问题,比例问题

国考省考行测&#xff1a;数量关系&#xff0c;牛吃草问题 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论…

〖Python网络爬虫实战㉘〗- Selenium案例实战(二)

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…

图神经网络(处理点云)PPFNet的实现

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook和有关文献。超链。提取码8848。 文章目录 前言文献阅读代码实操历史遗留问题 前言 本篇文章接上一篇文章…

今年的面试难度,我给跪了……

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…

【STM32G431RBTx】备战蓝桥杯嵌入式→决赛试题→第七届

文章目录 前言一、题目二、模块初始化三、代码实现interrupt.h:interrupt.h:main.h:main.h: 四、完成效果五、总结 前言 无 一、题目 二、模块初始化 1.LCD这里不用配置&#xff0c;直接使用提供的资源包就行 2.ADC:开启ADCsingle-ended 3.LED:开启PC8-15,PD2输出模式就行了…

手撕代码——同步FIFO

手撕代码——同步FIFO 一、FIFO原理与设计二、完整代码与仿真结果三、仿真结果 一、FIFO原理与设计 查看Xilinx官方FIFO IP核&#xff0c;其主要的信号有时钟信号、写端口信号、读端口信号&#xff0c;其中&#xff0c;写端口信号包括写满信号full、写使能信号wr_en、写数据输入…

[元带你学: eMMC完全解读 7] eMMC 设备与系统概述

依JEDEC eMMC 5.1及经验辛苦整理,付费内容,禁止转载。 所在专栏 《元带你学: eMMC完全解读》 前言 全文3600 字, 全文介绍eMMC 内部系统框架, Bus 总线宽度, 总线Speed Mode, 了解即可。对应Bus 总线重点看 8 Bit 即可, Speed Mode 重点看 HS400。几乎所有的系统都是跑在…

Java并发编程-synchronized

目录 1. synchronized在jdk 1.6中的优化 1.1 锁消除 1.2 锁粗化 1.2 锁升级/锁膨胀 1.2.1 锁升级原理 1.2.2 自适应自旋锁 2. synchronized实现原理 3. synchronized和Lock的对比 1. synchronized在jdk 1.6中的优化 在JDK1.5的时候,Doug Lee推出了ReentrantLock,lock的…

【密码学复习】第九讲 密钥管理(一)

密钥管理简介 • 柯克霍夫斯原则(Kerckhoffs Principle) 即使密码系统的任何细节已为人悉知&#xff0c;只要密钥未泄漏&#xff0c;它也应是安全的(19世纪). 密钥安全&#xff1a;三分技术&#xff0c;七分管理 密钥管理就是在授权各方之间实现密钥关系的建立和维护…

dom4j 读取xml配置文件,根据配置文件利用反射创建对象

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

maven打包命令打出的可执行的jar包和可依赖的jar包的区别

目录 引出问题: 介绍打包插件 下面开始打包: 解压比较这两个jar包的区别: 引出问题: 当我建了一个maven的springboot项目A写了一个工具类,我把A项目打包成jar包去给B项目用,结果 B项目报错找不到这个jar包. 百度后发现原来jar包分为可执行jar包和可被依赖的jar包 介绍打包…