【C++】 认识多态 + 多态的构成条件详细讲解

前言
C

目录

    • 1. 多态的概念
    • 2 多态的定义及实现
      • 2 .1 虚函数:
      • 2 .2 虚函数的重写:
        • 2 .2.1 虚函数重写的两个例外:
      • 2 .3 多态的两个条件(重点)
      • 2 .4 析构函数为啥写成虚函数
    • 3 新增的两个关键字
      • 3.1 final的使用:
      • 3.2 override :
    • 4 抽象类
      • 4.1 概念
    • 5 多态的原理

1. 多态的概念

通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态. 一个接口,多种行为。
重写其实是一种接口继承

2 多态的定义及实现

2 .1 虚函数:

虚函数: 即被 virtual 修饰的类成员函数称为虚函数。

class Person
{
public:virtual void BuyTicket() { cout << "买票-全价" << endl; }
};

2 .2 虚函数的重写:

虚函数的重写(覆盖):

  • 派生类中有一个跟基类完全相同的虚函数
  • 即派生类虚函数与基类虚函数的返回值类型函数名字参数列表完全相同(三同)
  • 称子类的虚函数(重写)了基类的虚函数,也叫(覆盖)
    不符合重写,就构成隐藏。。。
class Person {
public:
virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
virtual void BuyTicket() { cout << "买票-半价" << endl; }
/*注意:子类虚函数不加Virtual,依旧构成重写(实际最好加上)*/
2 .2.1 虚函数重写的两个例外:
  1. 协变—基类与派生类虚函数返回值类型不同:

派生类重写基类虚函数时,与基类虚函数返回值类型不同。
即基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变

  • [ ] 协变的返回值类型可以不同,要求必须是(父子关系)的指针和引用
class A{};
class B : public A {};
class Person {
public:
virtual A* f() {return new A;}
};
class Student : public Person {
public:
virtual B* f() {return new B;}
};

2.析构函数的重写

  • 如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同
  • 虽然函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor
class Person {
public:
virtual ~Person() {cout << "~Person()" << endl;}
};
class Student : public Person {
public:
virtual ~Student() { cout << "~Student()" << endl; }
};

2 .3 多态的两个条件(重点)

  • 必须通过基类的指针或者引用调用虚函数
  • 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写
    在这里插入图片描述

2 .4 析构函数为啥写成虚函数

1.析构函数不构成多态的情况:
在这里,析构函数默认是隐藏关系

class Person {
public:~ Person () {cout << "~ Person( )" << endl;}
};
class Student : public Person {
public:~ Student () {cout << "~ Student ( )" << endl;}};

2.析构函数构成多态:

class Person {
public:virtual  ~ Person () {cout << "~ Person( )" << endl;}
};
class Student : public Person {
public:virtual ~ Student () {cout << "~ Student ( )" << endl;}};

其析构函数最好定义为虚函数。见下面的例子:

  • 指向谁,就调用谁析构。
    在这里插入图片描述
    在这里插入图片描述

3 新增的两个关键字

  • C++11提供了override和final两个关键字,可以帮助用户检测是否重写。

3.1 final的使用:

final:修饰虚函数,表示该虚函数不能再被重写。

class Car
{
public:
virtual void Drive() final {}
};
class Benz :public Car
{
public:
virtual void Drive() {cout << "Benz-舒适" << endl;}
};

3.2 override :

检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

class Car{
public:
virtual void Drive(){}
};
class Benz :public Car {
public:
virtual void Drive() override {cout << "Benz-舒适" << endl;}
};

重载、覆盖(重写)、隐藏(重定义)的对比
在这里插入图片描述

  • 同名的成员变量也是隐藏的关系

4 抽象类

4.1 概念

  • 在虚函数的后面写上 =0 ,则这个函数为纯虚函数。
  • 包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象
  • 派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。
  • 纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承
class Car
{
public:
virtual void Drive() = 0;
};
class Benz :public Car
{
public:
virtual void Drive()
{
cout << "Benz-舒适" << endl;
}
};

5 多态的原理

class Base
{
public:virtual void Func1()
{cout << "Func1()" << endl;
}
private:
int _b = 1;
};

通过观察测试我们发现b对象是8bytes,除了_b成员,还多一个__vfptr放在对象的前面(注意有些
平台可能会放到对象的最后面,这个跟平台有关),对象中的这个指针我们叫做虚函数表指针
在这里插入图片描述

  • 普通函数调用,编译链接时确定函数的地址,运行时直接调用。
  • **多态调用,**程序运行时去指向对象的虚表中找到函数的地址,进行调用。

总结:
多态的本质原理,当符合多态的两个条件时,
那么调用时,会到指向对象的虚表中找到对应的虚函数地址,进行调用

尾声
看到这里,相信大家对这个C++有了解了。
如果你感觉这篇博客对你有帮助,不要忘了一键三连哦

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

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

相关文章

09_电子设计教程基础篇(电阻)

文章目录 前言一、电阻原理二、电阻种类1.固定电阻1、材料工艺1、线绕电阻2、非线绕电阻1、实心电阻1、有机实心电阻2、无机实心电阻 2、薄膜电阻&#xff08;常用&#xff09;1、碳膜电阻2、合成碳膜电阻3、金属膜电阻4、金属氧化膜电阻5、玻璃釉膜电阻 3、厚膜电阻&#xff0…

vue2实现生成二维码和复制保存图片功能(复制的同时会给图片加文字)

<template><divstyle"display: flex;justify-content: center;align-items: center;width: 100vw;height: 100vh;"><div><!-- 生成二维码按钮和输入二维码的输入框 --><input v-model"url" placeholder"输入链接" ty…

智能家居1 -- 实现语音模块

项目整体框架: 监听线程4&#xff1a; 1. 语音监听线程:用于监听语音指令&#xff0c; 当有语音指令过来后&#xff0c; 通过消息队列的方式给消息处理线程发送指令 2. 网络监听线程&#xff1a;用于监听网络指令&#xff0c;当有网络指令过来后&#xff0c; 通过消息队列的方…

SpringSecurity6 学习

学习介绍 网上关于SpringSecurity的教程大部分都停留在6以前的版本 但是&#xff0c;SpringSecurity6.x版本后的内容进行大量的整改&#xff0c;网上的教程已经不能够满足 最新的版本使用。这里我查看了很多教程 发现一个宝藏课程&#xff0c;并且博主也出了一个关于SpringSec…

【python】条件语句与循环语句

目录 一.条件语句 1.定义 2.条件语句格式 &#xff08;1&#xff09;if &#xff08;2&#xff09;if-else &#xff08;3&#xff09;elif功能 &#xff08;4&#xff09;if嵌套使用 3.猜拳游戏 二.循环语句 1. while循环 2.while嵌套 3.for循环 4.break和conti…

被问了n遍的小程序地理位置权限开通方法

小程序地理位置接口有什么功能&#xff1f; 在平时我们在开发小程序时&#xff0c;难免会需要用到用户的地理位置信息的功能&#xff0c;小程序开发者开放平台新规要求如果没有申请开通微信小程序地理位置接口( getLocation )&#xff0c;但是在代码中却使用到了相关接口&#…

人工智能概述与入门基础简述

人工智能&#xff08;AI&#xff09;是计算机科学的一个分支&#xff0c;它致力于创建能够执行通常需要人类智能的任务的机器。这篇科普文章将全面介绍人工智能的基本概念、发展历程、主要技术、实际应用以及如何入门这一领域。 一、人工智能的定义与发展历程 人工智能的概念…

springboot版本升级,及解决springsecurity漏洞问题

背景&#xff1a; 项目中要解决 Spring Security RegexRequestMatcher 认证绕过漏洞&#xff08;CVE-2022-22978&#xff09; 漏洞问题&#xff0c;并且需要将项目的版本整体升级到boot版本2.1.7&#xff0c;升级改造过程非常的痛苦&#xff0c;一方面对整个框架的代码不是很熟…

六淳科技IPO终止背后:十分着急上市,大额分红,实控人买豪宅

华西证券被暂停保荐业务资格6个月的影响力逐渐显现。 近日&#xff0c;深圳证券交易所披露的信息显示&#xff0c;东莞六淳智能科技股份有限公司&#xff08;下称“六淳科技”&#xff09;及其保荐人撤回上市申请材料。因此&#xff0c;深圳证券交易所决定终止对其首次公开发行…

LangChain 概念篇(喂饭级)

LangChain 介绍 LangChain 是一个用于开发由语言模型驱动的应用程序的框架。 LangChain 框架的设计目标 支持应用程序让其不仅会通过 API 调用语言模型&#xff0c;而且还会数据感知&#xff08;将语言模型连接到其他数据源&#xff09;&#xff0c;Be agentic&#xff08;允…

专注 APT 攻击与防御—基于UDP发现内网存活主机

UDP简介&#xff1a; UDP&#xff08;User Datagram Protocol&#xff09;是一种无连接的协议&#xff0c;在第四层-传输层&#xff0c;处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点&#xff0c;也就是说&#xff0c;当报文发送之后&#xf…

spring高级篇(十)

1、内嵌tomcat boot框架是默认内嵌tomcat的&#xff0c;不需要手动安装和配置外部的 Servlet 容器。 简单的介绍一下tomcat服务器的构成&#xff1a; Catalina&#xff1a; Catalina 是 Tomcat 的核心组件&#xff0c;负责处理 HTTP 请求、响应以及管理 Servlet 生命周期。它包…

OpenHarmony实战开发-应用侧调用前端页面函数

应用侧可以通过runJavaScript()方法调用前端页面的JavaScript相关函数。 在下面的示例中&#xff0c;点击应用侧的“runJavaScript”按钮时&#xff0c;来触发前端页面的htmlTest()方法。 前端页面代码。 <!-- index.html --> <!DOCTYPE html> <html> <…

图片浏览器-PicView

一、前言 PicView 是一款适用于 Windows 10 或 11 的快速高效的图像查看器&#xff0c;配备了干净简洁的用户界面&#xff0c;可以在不需要时方便地隐藏。 二、支持类型 它支持广泛的图像文件类型&#xff0c;包括&#xff1a;WEBP、GIF、SVG、PNG、JXL、HEIC、PSD 三、软件特…

红日靶场ATTCK 1通关攻略

环境 拓扑图 VM1 web服务器 win7&#xff08;192.168.22.129&#xff0c;10.10.10.140&#xff09; VM2 win2003&#xff08;10.10.10.135&#xff09; VM3 DC win2008&#xff08;10.10.10.138&#xff09; 环境搭建 win7&#xff1a; 设置内网两张网卡&#xff0c;开启…

CNN笔记详解

CNN(卷积神经网络) 计算机视觉&#xff0c;当你们听到这一概念的是否好奇计算机到底是怎样知道这个图片是什么的呢&#xff1f;为此提出了卷积神经网络&#xff0c;通过卷积神经网络&#xff0c;计算机就可以识别出图片中的特征&#xff0c;从而识别出图片中的物体。看到这里充…

Python安装以及环境配置

目录 一、下载安装包二级目录三级目录 一、下载安装包 方式网址Python官网python.org镜像下载地址Download pythonpycharmDownload PyCharm https://blog.csdn.net/sun80760/article/details/135256627 二级目录 三级目录

认识ansible 了解常用模块

ansible是什么&#xff1f; Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。是自动化运维工具&#xff0…

机器人操作系统ROS2学习 1

随着智能化时代的进程&#xff0c;机器人也在向着高度智能化的方向发展&#xff0c;这对应的机器人操作系统也就相应而生了。机器人操作系统ROS (Robot Operating System)的诞生为机器人系统的开发与应用带来了很大方便&#xff0c;也聚集了全球大量的应用开发人员推动ROS的发展…

hadoop学习---基于Hive的数仓搭建增量信息拉链表的实现

拉链表就是SCD2&#xff0c;它的优点是即满足了反应数据的历史状态&#xff0c;又能在最大程度上节省存储。 拉链表的实现需要在原始字段基础上增加两个新字段&#xff1a; start_time(表示该条记录的生命周期开始时间——周期快照时的状态)end_time(该条记录的生命周期结束时…