C++语法|虚函数与多态详细讲解(六)|如何解释多态?(面试向)

系列汇总讲解,请移步:
C++语法|虚函数与多态详细讲解系列(包含多重继承内容)

多态分为了两种,一种是静态的多态,一种是动态的多态。

静态(编译时期)的多态

函数重载

bool compare(int, int) {}
bool compare(double, double) {}

函数名字都是一个名字,但是参数个数都不相同,最终我们代码里面调用的是哪个函数,编译器是知道的:
函数源码和汇编如下

compare(10, 20); //call compare_int_int
compare(10.5, 20.5); //call compare_double_double

从汇编代码可以看出,到底调用哪个函数,编译时就已经确定了。

模版(函数模版和类模版)

函数模版?模版函数?深入理解函数与模板与分文件编写,我在这篇文章中的第一部分CPU眼里的模版明确写出了底层的汇编代码。具体可以去看文章。

template<typename T>
bool compare(T a, T b){}

compare<int>(10, 20); //call compare<int>(int, int)
compare<double>(10.2, 20.2); //call compare<double>(double, double)

动态(运行时期)的多态

这里当然是我们回答的重点。

动态的多态指的是在继承结构中,基类指针(引用)指向派生类对象,通过该指针(引用)调用同名覆盖方法(虚函数),基类指针指向哪个派生类对象,就会调用哪个派生类对象的覆盖方法,称为多态!

怎么做到的呢?就是通过动态绑定来实现的。

指针指向的是什么类型的派生类对象,那就访问谁的虚函数指针vfptr,进而就访问谁的虚函数表vftable,最后从虚函数表拿出来的,当然就是对应的派生类对象的方法了。

面试回答以上内容基本就差不多了,下面我们一起来做一点儿实验:

多态实践

问题引入

我们提供以下类:
关系图如下:

class Animal {
public:
    Animal(string name) : _name(name) {}
    virtual void bark() {}
protected:
    string _name;
};

//一下是动物实体类
class Cat : public Animal {
public:
    Cat(string name) : Animal(name) {}
    virtual void bark() { cout << _name << " bark: miao miao !" << endl; }
};

class Dog : public Animal {
public:
    Dog(string name) : Animal(name) {}
    void bark() { cout << _name << " bark: wang wang !" << endl; }
};

class Pig : public Animal {
public:
    Pig(string name) : Animal(name) {}
    void bark() { cout << _name << " bark: heng heng !" << endl; }
};

提供一个全局方法,同时测试函数如下:

void bark(Cat &cat) { cat.bark(); }
void bark(Dog &dog) { dog.bark(); }
void bark(Pig &pig) { pig.bark(); }
int main () {
	Cat cat("猫咪");
	Dog dog("二哈");
	Pig pig("佩奇");
	bark(cat);
	bark(dog);
	bark(pig);
}

打印的话大家肯定也能想象出来,但是里面有一个问题:

  1. 如果我们想继承Animal继承更多的新动物呢?
  2. 由于需求变更,我们可能删除现有的动物?

那么这组API的设计是不是不太合理呢?

//这里的bark API接口无法做到我们软件设计的“开-闭”原则
//即对修改关闭,对扩展开放
void bark(Cat &cat) { cat.bark(); }
void bark(Dog &dog) { dog.bark(); }
void bark(Pig &pig) { pig.bark(); }

如果我们添了一个动物,我们就需要添加一个bark函数;如果删除一个动物,就需要删除一个bark函数,太不合理了!

这样的设计不能满足高内聚,低耦合的要求。

问题解决

还记得本系列中不断提及的,指针或引用的动态绑定是多态性的基础吗?我们现在这样写代码:

void bark (Animal *p) { p->bark(); } //Animal::bark是一个虚函数,所以是动态绑定
void bark (Animal &p) { p.bark(); }
int main () {
	Cat cat("猫咪");
	Dog dog("二哈");
	Pig pig("佩奇");
	bark(&cat);
	bark(&dog);
	bark(&pig);
    bark(cat);
	bark(dog);
	bark(pig);
}

使用指针或者引用,都能够完美解决问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pands使用openpyxl引擎实现EXCEL条件格式

通过python的openpyxl库&#xff0c;实现公式条件格式。 实现内容&#xff1a;D列单元格不等于E列同行单元格时标红。 #重点是formula后面的公式不需要“”号。 from openpyxl.styles import Color, PatternFill, Font, Border from openpyxl.styles.differential import Dif…

【设计模式】JAVA Design Patterns——Bytecode(字节码模式)

&#x1f50d;目的 允许编码行为作为虚拟机的指令 &#x1f50d;解释 真实世界例子 一个团队正在开发一款新的巫师对战游戏。巫师的行为需要经过精心的调整和上百次的游玩测试。每次当游戏设计师想改变巫师行为时都让程序员去修改代码这是不妥的&#xff0c;所以巫师行为以数据…

git push后一直卡在在Writing objects:问题

git push后一直卡在Writing objects: 解决&#xff1a;设置 git config --global http.postBuffer 5242880000在执行git push。 一般设置后就可以成功了&#xff0c;后面不用看。 2. 我这里结果又报错&#xff1a; fatal: protocol error: bad line length 8192 MiB | 107.46 …

【C++】d1

关键字&#xff1a; 运行、前缀、输入输出、换行 运行f10 前缀必须项&#xff1a; #include <iostream> using namespace std; 输入/输出&#xff1a; cin >> 输入 cout << 输出 语句通过>>或<<分开 换行 endl或者"\n"

想当安卓开发工程师?学习路线分享!

安卓开发学习路线 在前几篇文章中,对安卓开发岗位的岗位要求做了一些科普,本节文章将介绍安卓开发岗位的学习路线。 目前,网络上有很多面经、算法题解、算法课等学习资料,如何合理利用这些资料成为技术求职者的一大困惑。笔者整理了一份安卓开发岗位学习路线供大家参考,…

第四课 communcation服务-can配置第二弹

Davinci配置目标: 介绍DBC基本属性,并且配置出一个DBC。 将DBC导入到vector的davinci工具,生成我们想要的代码。 Davinci配置步骤: 1. 编辑DBC文件 DBC文件是一种非常重要的工具,所谓DBC就是Database CAN,CAN网络的数据库文件,定义了CAN网络的节点、消息、信号的所有…

网络安全知识核心20要点

1、什么是SQL注入攻击 概述 攻击者在 HTTP 请求中注入恶意的 SQL 代码&#xff0c;服务器使用参数构建数据库 SQL 命令时&#xff0c;恶意SQL 被一起构造&#xff0c;并在数据库中执行。 注入方法 用户登录&#xff0c;输入用户名 lianggzone&#xff0c;密码‘ or ‘1’’…

axios如何传递数组作为参数,后端又如何接收呢????

前端的参数是一个数组。 前端编写&#xff1a; 后端接收&#xff1a;

git解决版本冲突 -git pull

当在Git中遇到版本冲突时&#xff0c;通常是因为两个或更多的开发者在同一时间修改了同一个文件的相同部分&#xff0c;并将这些修改推送到远程仓库。Git无法自动合并这些修改&#xff0c;因此会产生冲突。以下是解决Git版本冲突的基本步骤&#xff1a; 拉取最新代码&#xff…

mybatis-plus 优雅的写service接口中方法(3)

多表联查 上文讲过了自定义sql &#xff0c;和wrapper的使用&#xff0c;但是我们可以发现 我们查询的都是数据库中的一张表&#xff0c;那么怎么进行多表联查呢&#xff0c;当然也是用自定义sql来进行实现 比如说 查询 id 为 1 2 4 的用户 并且 地址在北京 的 用户名称 普…

AI崛起,掌握它,开启智能新生活!

AI崛起&#xff0c;掌握它&#xff0c;开启智能新生活&#xff01; &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &…

LDAP: error code 32 - No Such Object

目前我的项目版本&#xff1a; Spring版本:5.3.15SpringBoot版本:2.6.3 完整错误 org.springframework.ldap.NameNotFoundException: [LDAP: error code 32 - No Such Object]; nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - No Such Objec…

Java进阶学习笔记9——子类中访问其他成员遵循就近原则

正确访问成员的方法。 在子类方法中访问其他成员&#xff08;成员变量、成员方法&#xff09;&#xff0c;是依照就近原则的。 F类&#xff1a; package cn.ensource.d13_extends_visit;public class F {String name "父类名字";public void print() {System.out.p…

[算法][前缀和] [leetcode]724. 寻找数组的中心下标

题目地址 https://leetcode.cn/problems/find-pivot-index/description/ 题目描述 代码 class Solution {public int pivotIndex(int[] nums) {int total Arrays.stream(nums).sum();//前缀和int prefixSum 0;int len nums.length;for(int i 0;i<len;i){if (i-1>0){p…

【已解决】C#设置Halcon显示区域Region的颜色

前言 在开发过程中&#xff0c;突然发现我需要显示的筛选区域的颜色是白色的&#xff0c;如下图示&#xff0c;这对我们来说不明显会导致我的二值化筛选的时候存在误差&#xff0c;因此我们需要更换成红色显示这样的话就可以更加的明显&#xff0c;二值化筛选更加的准确。 解…

若依 Ruoyi-Vue PageHelper 分页失效 total为记录数

分页插件PageHelper返回记录总数total竟然出错了 执行控制台的SQL&#xff0c;查询出来的total数量是对的&#xff0c;很奇怪分页的total设置为查询到的记录数。 怀疑对list.stream操作&#xff0c;影响了分页&#xff0c;代码发现确实是这样&#xff0c;debug&#xff0c;居然…

【Mac】跑猫RunCat for mac(菜单栏Cpu可视化监测工具) v10.3免费版安装教程

软件介绍 RunCat是一款为菜单栏提供关键帧动画的软件。动画速度会根据Mac的CPU使用情况而变化。奔跑的小猫通过运行速度告诉您Mac的CPU使用率。 这是一款好玩的软件&#xff0c;可以为您的Mac使用添加一点小确幸。感兴趣的朋友可以试试哦。 安装步骤 1.打开安装包&#xff0…

idea 出现 cpu占用100%

一、IDEA的CPU占用率过高 二、解决办法 idea安装路径bin目录 修改idea64.exe.vmoptions配置文件 原来的 -Xms128m -Xmx750m -XX:ReservedCodeCacheSize240m -XX:UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB50 修改为(IDEA优化内存配置) -Xms2048m -Xmx4096m -XX:Reser…

SpringCloudAlibaba:6.3SpringBoot接入RocketMQ

依赖 <?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 htt…