c++多态(二)

news/2024/9/23 4:26:43/

一、抽象类

在虚函数后面加 =0 , 这个虚函数就是纯虚函数。(此函数只声明不实现)

有纯虚函数的类是抽象类。(无法实例化对象)

上图Car是一个抽象类,他的子类由于继承了纯虚函数,如果在子类重写纯虚函数也会实例化不出对象。

只有重写继承的虚函数之后子类才能实例化对象。

虽然父类无法实例化对象,但是父类能定义指针,指向子类就能完成调用。

意义:强制派生类去完成重写,override 是已经重写了虚函数检查是否重写正确。

二、单继承和多继承的对象模型

1、单继承

class Base { 
public :virtual void func1() { cout<<"Base::func1" <<endl;}virtual void func2() {cout<<"Base::func2" <<endl;}
private :int a;
};
class Derive :public Base { 
public :virtual void func1() {cout<<"Derive::func1" <<endl;}virtual void func3() {cout<<"Derive::func3" <<endl;}virtual void func4() {cout<<"Derive::func4" <<endl;}
private :int b;
};

Derive对象模型如此下

2、多继承

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;
};

Derive对象模型如下

三、虚表与虚基表

虚继承中的表叫虚基表,存的是当前位置距离虚基类位置的偏移量。解决菱形继承问题。

虚表是虚函数表,存的是虚函数地址,目的是实现多态

虚函数和普通函数一样存在代码段。

虚函数表存在常量区(代码段)

四、菱形继承和菱形虚拟继承的对象模型

1、菱形继承

在32位下,D对象大小是28字节。

对象模型如下图

2、菱形虚拟继承

在32位下,D对象大小36字节。

对象模型如下图

五、多态基础知识总结

1、同类型实例化的对象虚表一样。

2、多态分类

多态分类多态类型
编译时多态重载,模板(早期绑定)
运行时多态重写,虚函数(晚期绑定,动态绑定)

3、函数如果参数是对象,则参数是哪个对象,就调用哪个对象中的函数,不管你是不是虚函数重写了。

函数参数如果是父类的指针或引用,且传入的是子类对象,完成重写后调用子类虚函数。

4、派生类没有虚表指针!

如果是完成子类重写的虚函数,那么子类虚函数地址是覆盖继承父类的那个虚表中原来的虚函数地址。

如果是子类没有完成重写的虚函数,虚函数地址存在第一个继承下来的父类的虚表中。

所以不管有没有虚函数的重写,派生类没有必要拥有自己的虚表指针。

5、虚函数的继承是接口的继承,重写函数实现,得到子类中不同于父类的函数。

普通函数的继承是复用父类的成员函数。

6、构造的顺序是声明的顺序,不是初始化类表的顺序,菱形虚拟继承的父类只会构造一次,因为父类共享。

7、虚表是在编译时生成。


http://www.ppmy.cn/news/1509887.html

相关文章

飞桨Paddle API index_add 详解

index_add paddle.index_add(x, index, axis, value, nameNone)[源代码] 沿着指定轴 axis 将 index 中指定位置的 x 与 value 相加&#xff0c;并写入到结果 Tensor 中的对应位置。这里 index 是一个 1-D Tensor。除 axis 轴外&#xff0c;返回的 Tensor 其余维度大小和输入 …

Qt+OpenCV配置和测试

一、前言 OpenCV作为比较大众化的跨平台计算机视觉开源库&#xff0c;可以运行在多种操作系统上&#xff0c;通过与Qt的结合&#xff0c;能够轻松的是实现一些图像处理和识别的任务&#xff0c;本文在Windows操作系统的基础上具体讲解Qt和OpenCV的配置和环境搭建方法&#xff…

【机器学习】Gans生成对抗网络入门

Generative Adversarial Networks&#xff0c;生成对抗网络。 从未学过AI&#xff0c;从超分辨率接触到这个概念&#xff0c;初步学习记录&#xff0c;受益匪浅&#xff0c;记录如下。 什么是生成对抗网络&#xff08;GANs&#xff09;&#xff1f; 2014年Goodfellow 等人启…

VUE最强学习宝典01

目录 1.Vue是什么&#xff1f; 2. 两种使用方法 3.创建第一个vue实例 4.补充小知识 5.错误查询 1.Vue是什么&#xff1f; 概念&#xff1a;动态构建用户界面的渐进式 JavaScript 框架 。 优点&#xff1a;大大提升开发效率(70%) 缺点&#xff1a;需要理解记忆规划-->官…

【生成式人工智能-十一一个不修改模型就能加速语言模型生成的方法】

一个加速语言模型生成的方法 现在语言模型的一个弊端speculative decoding预言家预测的问题 speculative decoding 模块的实现方法NAT Non-autoregressive模型压缩使用搜索引擎 一些更复杂些的speculative decoding 实现方式 speculative decoding 是一个适用于目前生成模型的加…

一台佳能G3811彩色喷墨打印机打印没颜色报5200的维修记录

一台佳能G3811彩色喷墨打印机,用户送修,称打印没有颜色,加电开机连电脑安驱动打印测试,确实没有颜色,于是清洗喷头结果打印机那个显示屏上 ,上来就报错P08,电脑提示5200; 话不多说,开始维修,仅记录当时的维修方法及步骤,其它未列出。。。 维修方法: 1、进维…

MDK常见概念

&#xff08;1&#xff09;typedef定义结构体类型 typedef struct {uint32_t BaudRate;uint32_t WordLength;uint32_t StopBits;uint32_t Parity;uint32_t Mode;uint32_t HwFlowCtl;uint32_t OverSampling; } UART_InitTypeDef; &#xff08;2&#xff09;寄存器 (3)DMA DMA 是…

快速搭建Vue_cli以及ElementUI简单项目学生管理系统雏形

为了帮助大家快速搭建Vue_cli脚手架还有ElementUI的简单项目,今天我给大家提供方法. 因为这个搭建这个项目步骤繁多,容易忘记,所以给大家提供这个资料希望可以帮助到你们. 废话不多说开始搭建项目: 搭建Vue_cli项目 首先点开HBuilder左上角的文件点击新建,点击项目,选择vue项…