C++ 当基类为抽象类时如何析构派生类

news2025/1/11 12:50:13

前言:本教程不涉及基础,稍微了解一下C++virtual多态的知识就可以了,不了解的话可以先去看一下菜鸟教程,也可以看我往期的文章《virtual》、《虚函数表》

多态分为静态多态和动态多态

静态多态:也成为编译时的多态;在编译时期就已经确定要执行了的函数地址了;主要有函数重载和函数模板。

动态多态:即动态绑定,在运行时才去确定对象类型和正确选择需要调用的函数,一般用于解决基类指针或引用派生类对象调用类中重写的方法(函数)时出现的问题。

我们今天讲的就是动态多态时,也就是基类指针指向派生类对象时,如何析构派生类;

先看代码:

#include <iostream>
using namespace std;

class Person
{
public:
	Person() { cout << "基类的构造函数" << endl; }
	virtual void show() = 0 ;
	~Person() { cout << "基类的析构函数" << endl; }
};

class Son :public Person
{
public:
	Son() { cout << "派生类Son的构造函数" << endl; }
	void show() { cout << "派生类Son的show函数" << endl; }
	~Son() { cout << "派生类Son的析构函数" << endl; }
};

class Teacher:public Person
{
public:
    Teacher() { cout << "派生类Teacher的构造函数" << endl; }
    void show() { cout << "派生类Teacher的show函数" << endl; }
    ~Teacher() { cout << "派生类Teacher的析构函数" << endl; }
};

int main()
{
	
}

我们创造了一个基类Person里面有构造、析构和一个show函数,子类Son和Teacher也一样

但是父类Father的show是virtual = 0、也就是说父类是个抽象类,不能实例化(创建)对象:

但是它可以创建指针,通过指针传入的对象来调用对应的show函数: 

(代码中忘记释放指针,是一种不好的习惯,大家不要学我,抱歉抱歉)

这也就实现了动态多态;

上面代码我想告诉大家的是:基类指针指向子类对象是一种很常见的用法 

知道了这一点之后,我们接着往下看:

当派生类对象构造时会先调用基类的构造函数、然后调用派生类的构造

析构的时候会先调用派生类的析构函数然后调用基类的析构函数;

这个流程是很完美的;

我们下面手动调用几次派生类的析构函数看看有什么反应:

 

我们发现每次调用派生类的析构函数析构之后都会自动调用一次基类的析构函数 

这是C++规定的;

我们回到刚才那句话“基类指针指向派生类对象”:

但是他少了一个步骤:析构派生类对象;

如果派生类中存放动态申请的指针,如果不释放是很危险的;那么要怎么释放呢?

手动调用派生类的析构吗?

我们试试:

 

这个指针他没有办法调用派生类的成员啊;派生类的析构是属于他自己的,父类的指针可以说是“碰不到”这个析构函数;

举个栗子:假设基类A有成员a和b,派生类B新增了成员c,那么基类的指针范围指向的就是8个字节的地址,但是成员c的地址是8-12字节;基类指针碰不到这个变量;可能有人会想到指针偏移,但是指针偏移寻找变量是可以的,如果是用来寻找函数呢?函数的内存地址不在类中啊,偏移有点太难了吧;

但是我们学过多态,我们知道,如果将函数前面加上virtual关键字,那么他的地址就会被写入虚表,基类指针可以通过指向子类对象来调用子类虚表中的重写函数;

所以我们只需要一个virtual关键字就可以了;

再次运行:

 

任务完成了;

最后补充一点细节:

基类中的纯虚函数也是可以实现的,像这样:

 

也可以不写:

 

但是,如果析构函数是纯虚函数,则必须实现:

 

如果不实现:

 

你编译的时候可能没问题,但是运行的话,会出错;因为派生类的对象析构了之后会调用基类的析构,但是你基类的析构函数没写实现他怎么调用?肯定会出错;

所以如果基类的析构函数声明为纯虚函数也就是virtual 函数声明 = 0则必须要写实现!!! 

可能会有人有问题:基类的析构函数为什么要设置为纯虚函数?既然虚函数就能满足多态,而且还必须要实现,那么为什么要设置为纯虚函数呢?

首先,只有存在纯虚函数的类才称为抽象类;抽象类是很常见的

但是有时候我们不知道该把哪一个函数设置为纯虚函数,这个时候把析构函数设置为纯虚函数是一个很完美的选择;

另外还有一点建议:对于基类来说,即使它不需要析构函数,也应该提供一个"虚析构函数",对于是否提供"纯虚析构函数"要看需求了;

文章至此结束,感谢观看!

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

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

相关文章

使用Word模板导出Word后,表格后面产生空白页

目录 背景 解决 参考 背景 项目中有导出Word功能,其实现逻辑是先整理一个Word文档,里面使用占位符;代码读取Word文档,然后替换占位符。 但出现这样的问题:填充某个表格后,表格后面出现了空白页。 解决 调查发现是段落标记导致的,如何显示段落标记?File -> Op…

生成对抗:DCGAN

DCGAN简介 Generative Adversarial Networks(GANs),GANs有两个模型组成,一个是生成器,用于训练生成假的数据,另一个是判别器,用于预测生成器的输出结果。其中生成器提供训练数据给判别器&#xff0c;提高判别器的准确率。判别器提供生成样本的预测结果&#xff0c;给生成器提供…

【Java系列】小小练习——带你回顾Java基本运算符

返回主篇章         &#x1f447; 【Java】才疏学浅小石Java问道之路 Java小练习1. 练习一1.1 题目1.2 题解(附解析)2. 练习二2.1 题目2.2 题解(附解析)3. 练习三3.1 题目3.2 题解(附解析)小结1. 练习一 1.1 题目 一个三位数&#xff0c;将其拆分为个位、十位、百位后…

mac安装cocoapods完整步骤

一、概念理解 首先不要急着搜索终端命令&#xff0c;你需要明白安装 cocoapods 都需要什么环境&#xff0c;这对于安装途中如果遇到问题该如何解决很重要&#xff0c;很重要&#xff0c;很重要&#xff01; 1、安装pods需要依赖 ruby 环境&#xff0c;而安装 ruby 你需要借助工…

[网鼎杯 2020 白虎组]PicDown(任意文件读取)

打开界面发现有一个get传参然后&#xff0c;尝试任意文件读取漏洞&#xff0c;/etc/passwd看一下,提示下载了一个jpg图片然后 打不开只能用 010查看一下信息 看来是猜对了&#xff0c;然后 如果日记没删掉可以查看历史记录 .bash_history呃呃呃差不到&#xff0c;那就看一下现…

Python 现代控制理论 —— 梯度下降法实现的线性回归系统

线性回归是有监督学习中的经典问题&#xff0c;其核心在于找到样本的多个特征与标签值之间的线性关系。样本集中的第j个样本可被表示为&#xff1a; 特征向量&#xff1a;标签值&#xff1a; 而线性回归系统给出权重向量&#xff1a; 使得该样本的预测值为&#xff1a; 当所有…

Python采集某网站m3u8内容,美女我来了~

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 环境使用: Python 3.8 Pycharm 模块使用: import requests >>> pip install requests import re 正则表达式 解析数据 import json 安装python第三方模块: win R 输入 cmd 点击确…

不止一面的百变 ACE

这个时代&#xff0c;可谓是云原生的黄金时代。 站在这个云原生的风口&#xff0c;年轻一代的开发者如何看待自己所处的环境&#xff1f;他们眼中的云原生未来是什么样&#xff1f; 今天我们就将走近一位年轻的“云原生原住民”&#xff0c;听听他作为开发者的成长经历。 War…

【python3】9.python高阶内容(上)_基础

9.python高阶内容&#xff08;上&#xff09;_基础 2022.12.27 python高阶内容&#xff08;上&#xff09;_基础9.1 字符串的高阶玩法 9.1.1 %百分号模式 %d:整数%i:整数%s:字符%f:小数 【方式1】&#xff1a;前面用格式占位&#xff0c;后面用具体的内容 name "莫烦…

Android设计模式详解之访问者模式

前言 访问者模式是一种将数据操作与数据结构分离的设计模式&#xff1b; 定义&#xff1a;封装一些作用于某种数据结构中的各元素的操作&#xff0c;它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作&#xff1b; 使用场景&#xff1a; 对象结构比较稳定&a…

大厂与小厂招人的区别,看完多少有点不敢相信

前两天在头条发了一条招人的感慨&#xff0c;关于大厂招人和小公司招人的区别。 大厂&#xff1a;有影响力&#xff0c;有钱&#xff0c;能够吸引了大量的应聘者。因此&#xff0c;也就有了筛选的资格&#xff0c;比如必须985名校毕业&#xff0c;必须35岁以下&#xff0c;不能…

基于DoIP使用CANoe对ECU进行诊断测试

伴随以太网引入到车载网络中,本文分享通过常用工具CANoe怎么样对ECU进行通信以及测试。 相比在车载CAN总线,以太网又有什么与众不同之处? 1、硬件接口卡(收发器) 以往车载CAN网络较常使用的是VN 16XX 系列,在连接ECU进行通信时,除了配置波特率也要进行通道分配: 而…

7个学习UI、UX设计一定要经历的步骤

我们不是一些有才华的设计师。我们天生就有艺术天赋。后天我们学会了设计技巧。设计的根本目的是解决问题。设计是不断发现和解决问题。 有许多设计领域&#xff1a;UI、UX.产品设计师.平面设计师.交互设计师.信息架构师等&#xff0c;所以要找出你最感兴趣的设计专业。 现在让…

美颜sdk动态贴纸技术、代码分析

目前&#xff0c;美颜sdk动态贴纸已经成了各大直播平台主播的必备“直播伴侣”&#xff0c;在其他的视频拍摄场景动态贴纸的热度同样很高&#xff0c;本篇文章小编将为大家深度盘点一下美颜sdk动态贴纸的技术实现以及代码。 一、多终端适配 对于如今的直播平台终端来说&#x…

CAPL学习之路-测试功能集函数(测试结构化)

用户可以使用如下函数在测试报告中对每一条测试用例设置结构化的输出内容 TestCaseDescription 添加测试用例的描述文本 此函数用于测试用例中,描述文本会添加在固定区域(测试用例title的下方)。多次调用该函数,描述文本会合并显示在固定区域。如果想让描述文本换行,可以…

爆火的Web3.0背后,百度营销如何抓住流量密码?

出品| 大力财经 文 | 魏力 AI、元宇宙、Web3.0、AIGC等新技术、新概念的加持&#xff0c;给传统的流量营销平台带来了前所未有的挑战。尤其是短视频时代的崛起&#xff0c;用户的使用习惯开始改变&#xff0c;完全改变了流量的逻辑和习惯。 从搜索引擎业务起家的百度&#x…

DoIP---车载以太网诊断方面边缘节点的路由策略分析

假期后开工第一天&#xff0c;规划好自己一天需要做的事情&#xff0c;按部就班完成每日任务&#xff0c;做好每日总结。 自己一天一个脚印&#xff0c;这不是鸡血&#xff0c;这是工作态度&#xff01;&#xff01;&#xff01; 惯例分享一段喜欢的文字&#xff1a; 每个人…

目标检测之FCOS算法分析

网络结构 (图片来自原论文&#xff1a;FCOS: Fully Convolutional One-Stage Object Detection) 在ResNet50 Backbone中&#xff0c;C3,C4,C5C3,C4,C5C3,C4,C5是卷积特征图&#xff1b; 在FPN结构中&#xff0c;P3,P4,P5,P6,P7P3,P4,P5,P6,P7P3,P4,P5,P6,P7是最后用于预测的特…

2023跨境出海指南:泰国网红营销白皮书

作为东南亚第二大经济体&#xff0c;泰国一直是旅游和企业出海的热门之地。随着电商经济和互联网的发展&#xff0c;加上疫情的催化&#xff0c;泰国的社交媒体行业也得到了飞速发展&#xff0c;已经成为了主流营销方式之一。本文Nox聚星就从网红营销的角度&#xff0c;和大家探…

代码随想录-46-226.翻转二叉树

目录前言题目1.使用队列思路&#xff08;定义变量&#xff09;2. 本题思路分析&#xff1a;3. 算法实现4. pop函数的算法复杂度5. 算法坑点前言 在本科毕设结束后&#xff0c;我开始刷卡哥的“代码随想录”&#xff0c;每天一节。自己的总结笔记均会放在“算法刷题-代码随想录…