C++多态讲解以及常见面试题

多态的概念

什么是多态
​ 多态就是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。

实现多态的条件

  1. 动态绑定多态(在运行时才知道函数的地址):

调用函数的对象是指针或引用。
被调用函数必须是虚函数,并且完成了虚函数的重写。

  1. 静态绑定多态(在编译时确定函数的地址):

函数重载

多态的作用

  封装是为了代码模块化,继承是扩展已存在的代码,他们的目的都是为了 实现代码的复用,但是多态的目的是为了实现接口的重用,也就是多不管传递过来的是哪个类对象,函数都能狗狗通过这个接口调用到适应自己对象的实现方法。
  虚函数重写:子类重写父类的函数(协变:子类中的返回值和父类中的返回值是父子关系,并且是引用或指针)。如果只在父类中添加virtual关键字,子类中的重写函数也会称为虚函数,童谣可以构成多态,否则为重定义。

函数重载、重定义、重写的区别:

  1. 函数的重载:在相同的作用域中,两个函数的参数不同,函数名相同,构成函数重载。
  2. 函数重定义:子类中有父类的同名函数,继承自父类的函数被隐藏,子类调用重写后的。
  3. 函数的重写:子类与父类的虚函数函数名、参数、返回值相同的函数,构成函数重写。

虚函数和纯虚函数

  虚函数就是在类的成员函数钱钱添加了virtual关键字。主要是为了实现多态,通过一张虚函数表来实现。它允许子类重写来自父类的成员函数。
  纯虚函数就是在基类中只对对应的虚函数进行声明,在最后加=0,定义纯虚函数的类是一个抽象类,抽象类不能被实例化,它体现的是接口继承,子类只是继承了这个接口的形式,不需要使用他里面的功能,要实现自己的功能。在子类中必须实现父类的纯虚函数,如果不实现父类的纯虚函数,这个子类也是一个抽象类,同样不能区实例化对象。
  那么什么是抽象类呢?抽象类就是包含纯虚函数的类,这个类不能被实例化,因为类定义的不完整,成员函数都没有实现,这种类只是为了接口继承的实现,继承他的子类并不想去用它,子类要实现自己的功能。
  无论是虚函数还是纯虚函数,都是在基类中为派生类提供编程接口,面向对象最核心的思想就是对接口编程,而不是对实现编程,在C++中,就是使用继承和多态来事项这种思想。如果想让基类为派生类提供缺省的处理方法,那么就将这个函数设为虚函数,如果是想让派生类必须重写该虚函数,就将这个函数设为纯虚函数。

1、虚函数和纯虚函数可以定义在同一个类中,一旦某个类包含了纯虚函数,这个类就是一个抽象类。
2、虚函数可以直接被使用,但是纯虚函数必须要在派生类中实现之后才可以使用,一i那位纯虚函数在积累中只声明没有定义,所以无法直接使用。
3、虚函数和纯虚函数都可以在子了中被重写,一堕胎的形式被调用。
4、虚函数和纯虚函数都是为了实现接口继承而出现。
5、虚函数的定义:virtual + 函数纯虚函数定义:virtual + 函数 + =0;
6、虚函数和纯虚函数都不能设为static,因为static在编译的时候就要被绑定,但是虚函数和纯虚函数实在运行时在确定的。

虚函数表

  虚函数表是一个函数指针数组,在末尾存放的时一个空指针nullptr,在VS中存放在代码段,在虚函数表中只存放虚函数执政,他不存放普通函数的指针,将新创建的虚函数指针存放在虚函数表末尾。
  虚标指针:存放在对象模型中,在32位机上,存放在对象模型的头4个字节中。

单继承中的虚表

  在单继承中所有的虚函数都存放在虚表中,如果有被重写的,直接将虚表中的虚函数指针换成重写后的虚函数指针即可,如果在子类中的添加了新的虚函数,按照新的虚函数的声明顺序将其添加到虚表中。在虚表中,先添加父类的虚函数指针,再添加子类的虚函数指针。

多继承中的虚表
#include <iostream>
using namespace std;
class base1
{
public:virtual void func1(){cout << "base1::func1" << endl;}virtual void func2(){cout << "base1::func2" << endl;}
private:int b1;
};
class base2
{
public:virtual void func1(){cout << "base2::func1" << endl;}virtual void func2(){cout << "base2::func2" << endl;}
private:int b2;
};
class derive:public base1, public base2
{
public:virtual void func1(){cout << "derive::func1" << endl;}virtual void func3(){cout << "derive::func3" << endl;}
private:int d1;
};
typedef void(*VFPTR)();	//函数指针
void printFunc(VFPTR* vftable)
{cout << "虚表地址" << vftable << endl;for (int i = 0; (*vftable) != nullptr; ++i){cout << "第" << i << "个函数地址" << *vftable  << "--->";(*vftable)();//调这个函数++vftable;//指针向后走,打印下一个函数地址}
}int main()
{derive d;//取虚标地址的方法://先取到d的地址,由于虚标指针存放在对象的头四个字节中,所以要将他转为int*类型(int* 位四个字节),这样就可以得到头四个字节的内容,对这个已经得到的四个字节解引用就可以得到它的值,但现在他是整型的,我们要的是函数指针,所以要将他强转位函数指针类型的指针就可以得到虚表的地址(VFPTR*)*((int*)&b);//如果要调用虚表中的第一个函数,对他向后偏移1个单位再解引用就可以调用虚表中的第一个函数(*(((VFPTR*)*((int*)&b))+1))();//打印第二个虚标地址//方法一://给出一个base2的指针,让他存放d的地址,这时候就发生了一个天然的转换,这个指针中存放的就是第二个虚表的地址base2* pd = &d;//方法二//让第一个虚表的地址向后偏移base1的大小(VFPTR*)*((int*)((char*)&b+sizeof(base1)))return 0;
}

接口继承和实现继承

  普通函数的继承就是一种实现继承,派生类继承了基类函数,继承的是函数的实现。
  虚函数的继承是接口继承,派生类继承的是基类函数的接口,目的是为了重写,从而达成多态,继承的是接口。如果不是为了实现多态,不要把函数设为虚函数。

—>常见面试题<—

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

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

相关文章

王飞跃谈GE艰难的数字化转型启示:从工业智联网到工业5.0

来源&#xff1a;德先生外患&#xff1a;2018年6月26日&#xff0c;通用电气&#xff08;下文称GE&#xff09;被剔除出道琼斯工业平均指数&#xff0c;而GE自1907年即是道指成分股&#xff0c;至今坚守了111年。2017年以来&#xff0c;通用电气股价从30美元左右下跌到现在的13…

一篇文章搞懂数据仓库:常用ETL工具、方法

目录 一、什么是ETL&#xff1f; 二、ETL & ELT 三、常用的ETL工具 3.1 sqoop 3.2 DataX 3.3 Kettle 3.4 canal 3.5 StreamSets 四、ETL加载策略 4.1 增量 4.2 全量 4.3 流式 小编有话 一、什么是ETL&#xff1f; ETL&#xff0c;是英文Extract-Transform-Lo…

经典排序之 堆排序

开了个公众号「aCloudDeveloper」&#xff0c;专注技术干货分享&#xff0c;期待与你相遇。 Author: bakari Date: 2012.7.30 排序算法有很多种&#xff0c;每一种在不同的情况下都占有一席之地。关于排序算法我分“经典排序之”系列分别述之。本篇为堆排序。 堆排序是运用二叉…

操作系统之进程概念

进程概念 进程是什么&#xff1a; 表面上来说进程是程序的一个执行实例&#xff0c;或者是一个正在执行的程序等&#xff0c;从操作系统的角度来说&#xff0c;程序运行需要将代码数据加载到内存中&#xff0c;由于在操作系统中运行了很多的程序&#xff0c;操作系统就必须去管…

也谈压缩感知和贝叶斯大脑

来源&#xff1a;科学网压缩感知和人工智能都是当下很热很热的研究课题。不过许多论文数学论述高深莫测&#xff0c;加之一大堆各种千奇百怪的数学符号&#xff0c;不仅让人望而生畏&#xff0c;望而却步。笔者对希望用形象的比喻把问题大致轮廓讲清楚就好。所谓压缩感知是什么…

一篇文章搞懂数据仓库:三种事实表(设计原则,设计方法、对比)

目录 1、三种事实表概述 2、三种事实表对比 3、事实表设计 8 大原则 4、事实表设计方法 第一步&#xff1a;选择业务过程及确定事实表类型 第二步&#xff1a;声明粒度 第三步&#xff1a;确定维度 第四步&#xff1a;确定事实 事实表作为数据仓库维度建模的核心&#…

Eclipse快捷键一览

基本使用 Ctrl1 快速修复(最经典的快捷键,就不用多说了)CtrlD: 删除当前行 CtrlAlt↓ 复制当前行到下一行(复制增加)CtrlAlt↑ 复制当前行到上一行(复制增加)Alt↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)Alt↑ 当前行和上面一行交互位置(同上)Alt← 前一…

深思考人工智能蝉联SMP2018多轮语义对话冠军,报告解读多轮人机对话实现过程...

人机对话技术近年来受到了学术界和产业界的广泛关注&#xff0c;其发展影响并推动着语音识别与合成、自然语言理解、对话管理以及自然语言生成等研究的进展。众多产业界巨头相继推出了人机对话技术相关产品&#xff0c;并将人机对话技术作为其公司的重点研发方向。8月3日&#…

操作系统之动态库和静态库

什么是库&#xff1f; 平时在写代码的时候会经常添加一些头文件&#xff0c;添加这些头文件其实是让编译器从一个目录下去寻找这个文件&#xff0c;这个目录就是我们常说的库。在Linux中库一般存放在user/lib目录。库就是将一些常用的函数的目标文件打包在一起&#xff0c;提供…

一篇文章搞懂数据仓库:数据仓库规范设计

目录 一、为什么要进行规范设计&#xff1f; 二、设计规范 - 指标 三、命名规范 - 表命名 3.1 常规表 3.2 中间表 3.3 临时表 3.4 维度表 四、开发规范 五、流程规范 一、为什么要进行规范设计&#xff1f; 无规矩、不方圆。规范设计是在具体开发工作之前制定的&…

asm字节码操作 方法的动态修改增加

asm 4.0 版本 http://forge.ow2.org/plugins/scmsvn/index.php?group_id23 asm是java的字节码操作框架&#xff0c;可以动态查看类的信息&#xff0c;动态修改&#xff0c;删除&#xff0c;增加类的方法。 下面基于4.0版本的一个使用示例&#xff0c;演示了对类Foo进行修改方法…

vim基本命令

最实用的几个&#xff1a; 0&#xff08;数字0&#xff09;移动到本行第一个字符上 $ 移动到行尾 。 3$ 移动到下面3行的行尾 gg 移动到文件头。 [[ G&#xff08;shift g&#xff09; 移动到文件尾。 ]] /text  查找text&#xff0c;按n健查找下一个&#xff0c;按…

map的详解及常见面试题

map的概念 map是STL中的一个关联式容器&#xff0c;它提供一对一的K-V的数据处理能力&#xff0c;由于这个特性&#xff0c;在我们需要完成Key-Value数据处理的时候可以很方便的调用。map的底层结构是红黑树&#xff0c;这棵树对数据有自动排序的功能&#xff0c;所以map中的数…

无处不在的人工智能,IBM沃森的20个行业应用

来源&#xff1a;资本实验室聚焦前沿科技创新与传统产业升级自2011年在美国综艺电视节目《危险边缘》中一战成名后&#xff0c;IBM的Watson就一直是最受关注的人工智能之一。从菜谱分析到球队管理&#xff0c;从健康顾问到酒店礼宾服务&#xff0c;Watson基于自然语言处理和机器…

自定义店招应该具有的基本功能

今天正式开始制作我的第一套SDK2.0模板。 首先是制作店铺的招牌&#xff0c;因为我个人习惯把首页的样式先制作在PSD中&#xff0c;然后参照PSD&#xff0c;由上至下进行编码实现&#xff01;在此前&#xff0c;我一度想过使用默认的店招&#xff0c;但是他真的是太不方便了&a…

一篇文章搞懂数据仓库:数据仓库架构-Lambda和Kappa对比

在介绍Lambda和Kappa架构之前&#xff0c;我们先回顾一下数据仓库的发展历程&#xff1a; 传送门-数据仓库发展历程 写在前面 咳&#xff0c;随着数据量的暴增和数据实时性要求越来越高&#xff0c;以及大数据技术的发展驱动企业不断升级迭代&#xff0c;数据仓库架构方面也在…

epoll精讲

epoll - I/O event notification facility 在linux的网络编程中&#xff0c;很长的时间都在使用select来做事件触发。在linux新的内核中&#xff0c;有了一种替换它的机制&#xff0c;就是epoll。 相比于select&#xff0c;epoll最大的好处在于它不会随着监听fd数目的增长而降…

宇宙和你,本质上其实只是个八维数字?

剑桥大学的数学物理学家Cohl Furey正在寻找粒子物理标准模型和八元数之间的联系。八元数的乘法规则被编码在被称为法诺面的三角图中。来源&#xff1a; 环球科学对于一维、二维乃至四维的数字&#xff0c;人们都不陌生&#xff1a;一维的实数一直都存在于经典物理中&#xff0c…

Fedora 安装QQ2012

1.下载软件包&#xff1a;http://www.everbox.com/f/yLDb2jlpP9WBVvXlSkzC5JKuD9 2.依次执行一下命令 cd /root # 文件存储路径 tar -zxvf qq2012.tar.gz -C /opt # 解压到/opt路径下&#xff0c;注意权限 cd /opt ls cd qq2012/wineapp/qq/ ls ./ins…

一篇文章搞懂数据仓库:数据应用--OLAP

目录 1、OLAP和OLTP的区别 2、OLAP分类 3、OLAP基本操作 4、OLAP选型 1、olap和oltp的区别 OLTPOLAP对象业务开发人员分析决策人员功能日常事务处理面向分析决策模型关系模型多维模型数据量几条或几十条记录&#xff1e;百万于万条记录操作类型增、删、查、改(CRUD)查询为主…