c++第八天-多态

  1. 虚函数
  2. 虚析构函数
  3. 纯虚函数与抽象类

多态实现的条件:(1)公有继承 (2)派生类重写基类虚函数 (3)基类指针/引用指向派生类对象

虚函数不能是构造函数,不能是静态函数,不能是友元函数,只能是普通的成员函数。

其中,绑定的含义是什么?

绑定分为两类,一类是静态绑定,一类是动态绑定

静态绑定:在编译阶段,普通成员函数、全局函数、重载函数这些都是静态绑定

动态绑定:在运行阶段,程序才能确定函数调用对应的具体函数,只有virtual声明的虚函数,并且用基类指针引用调用时,此案呢个发生动态绑定。

绑定就是确定函数调用到底会执行哪一个函数体的过程。

静态绑定就是在编译时绑定,动态绑定就是在运行时绑定。

绑定就是“函数调用和函数实现之间的对应关系是何时确定”的过程。

 基类声明了虚函数,产生虚函数表,将虚函数放入。类多一个隐含的虚函数指针,指向虚函数表。派生类继承时,会更新虚函数指针,指向自己的虚函数表,派生类重写的虚函数会放入派生类的虚函数表中。基类指针/引用指向派生类对象的时候,通过指针/引用调用虚函数时,会先通过派生类对象的虚函数指针到虚函数表中查找,如果有就会调用派生类的虚函数。

通过对象名无法实现多态。

#include<iostream>
using namespace std;class A{
public:virtual void func() {cout << "A::func" << endl;}
};class B : public A{
public:void func() {cout << "B::func" << endl;}
};int main()
{A* pa = new B();pa->func();     //多态,基类用指针调用派生类的虚函数A a;B b;a = b;a.func();   //不是多态,对象名无法调用派生类的成员函数,C++语法规则return 0;
}

补充:override/final

因为基类中声明了虚函数,这个函数在派生类中即使不加virtual,它在派生类中仍然是虚函数。所以在类的多层继承的情况下,一个成员函数很难看出是不是虚函数,可以通过override确保这个函数在某个基类中声明过虚函数,那么他就是虚函数。

class A{
public:    virtual void func() {cout << "A::func()" << endl;}void show() {cout << "A::show" << endl;}
};class B : public A{
public:void func() override {cout << "B::func" << endl;}void show() override {cout << "B::show" << endl;}
};

final: 修饰类时表示类不能被继承;修饰虚函数时表示虚函数不能被重写。

虚析构函数

         构造函数不能声明为虚函数,原因是构造函数在对象创建完之前调用的,此时还没有虚函数表和虚函数指针。

        析构函数在对象释放时调用,此时对象已经创建完成了,所以它有条件声明为虚函数。而且,应该声明成虚函数。

        如果析构函数不是虚函数的话,基类指针指向派生类对象,通过基类指针释放对象空间时,只会调用基类析构函数,而不会调用派生类析构函数,这样会导致派生类中的动态内存单元不被释放。

 

#include<iostream>
using namespace std;
class Base {			//基类Base
public:virtual ~Base();		//虚析构函数
};Base::~Base() {cout << "Base类析构函数" << endl;
}class Derive :public Base {		//派生类Derive公有继承Base类
public:~Derive();		//虚析构函数
};Derive::~Derive()
{cout << "Derive类析构函数" << endl;
}int main() {Base* pb = new Derive;		//基类指针指向派生类对象delete pb;return 0;
}

纯虚函数与抽象类

当基类非常抽象时,它的函数代码不好实现,不能只写出函数原型,而不写代码,定义这个函数的目的,是为了规范它的所有派生类都必须要有的函数,它的作用相当于接口。

纯虚函数定义的语法:

virtual 函数返回值类型函数名(参数列表) =  0

如果一个类中包含纯虚函数,这样的类称为抽象类。

抽象类的作用就是为了定义接口,方便实现多态。

抽象类不能创建对象,只能作为基类派生。

抽象类中如果有多个纯虚函数,派生类没有全部实现,此时派生类仍然是抽象类。

 

#include<iostream>
using namespace std;class Animal{   //动物类Animal
public:virtual void speak() = 0;   //纯虚函数virtual void eat() = 0;     //纯虚函数virtual ~Animal();          //析构函数
};Animal :: ~Animal()
{cout << "调用Animal析构函数" << endl;
}class Cat : public Animal{
public:void speak();void eat();~Cat();
};void Cat :: speak() {cout << "小猫喵喵叫" << endl;}
void Cat :: eat() {cout << "小猫吃鱼" << endl;}
Cat :: ~Cat() {cout << "调用Cat析构函数" << endl;}
class Rabbit :public Animal {	//兔子类Rabbit公有继承Animal类
public:void speak();		//声明speak()函数void eat();		//声明eat()函数~Rabbit();		//声明析构函数
};
void Rabbit::speak() { cout << "小兔子咕咕叫" << endl; }
void Rabbit::eat() { cout << "小兔子吃白菜" << endl; }
Rabbit::~Rabbit() { cout << "调用Rabbit析构函数" << endl; }int main() {Animal* pa = new Cat;	//定义基类指针pC指向Cat类对象pa->speak();		//通过pC指针调用speak()函数pa->eat();		//通过pC指针调用eat()函数delete pa;		//释放指针pC指向的空间pa = new Rabbit;	//定义基类指针pR指向Rabbit类对象pa->speak();		//通过pR指针调用speak()函数pa->eat();		//通过pR指针调用eat()函数delete pa;		//释放pR指向的空间return 0;
}

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

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

相关文章

全景图渲染Vue3+TS使用Photo Sphere Viewer插件实现

1.Photo Sphere Viewer插件安装: title=插件安装 体验AI代码助手 代码解读复制代码npm install photo-sphere-viewer -S 或 yarn add photo-sphere-viewer -S 2.原始全景图展示 初始化标签容器 体验AI代码助手 代码解读复制代码 // 全景图的根节点必须要具备宽高 TS引用,创建…

Redis之分布式锁(3)

这篇文章我们来详细介绍一下如何正确地基于Redis实现分布式锁。 基于Redis的分布式锁实现 组件依赖 首先通过Maven引入Jedis开源组件&#xff0c;在pom.xml文件加入下面的代码&#xff1a; <dependency><groupId>redis.clients</groupId><artifactId&g…

Java课堂笔记11

三个修饰符 一、abstract&#xff08;抽象&#xff09; 1.抽象方法只能在抽象的类里&#xff0c;只有方法的声明&#xff0c;没有方法的实现。&#xff08;没有{}直接&#xff1b;结尾&#xff09;。 2.abstract修饰的类称为抽象类。 注意&#xff1a;&#xff08;1&#x…

Linux 核心知识点整理(高频考点版)

一、编译与工具链 GCC 编译流程 四阶段&#xff1a;预处理&#xff08;-E&#xff0c;处理头文件 / 宏&#xff09;→ 编译&#xff08;-S&#xff0c;生成汇编&#xff09;→ 汇编&#xff08;-c&#xff0c;生成目标文件&#xff09;→ 链接&#xff08;生成可执行程序&…

轻量化社交管理方案:Skout与云手机的巧妙搭配

在移动社交时代&#xff0c;许多用户开始尝试通过多账号管理来拓展社交圈层。近期测试了Skout社交平台与亚矩阵云手机的搭配使用&#xff0c;发现这个组合为轻量级社交账号管理提供了一个值得关注的解决方案。 基础功能介绍 这套组合的核心优势在于&#xff1a; 通过云手机实…

ETL连接器好用吗?如何实现ETL连接?

目录 一、ETL连接器的功能和优势 1. 数据抽取能力 2. 数据转换功能 3. 数据加载功能 4. 优势总结 二、实现ETL连接的步骤 1. 需求分析 2. 选择合适的ETL连接器 3. 配置数据源和目标系统 4. 设计ETL流程 5. 开发和测试ETL任务 6. 部署和监控ETL任务 三、ETL连接器在…

uniapp实现聊天中的接发消息自动滚动、消息定位和回到底部

前言 前言无需多言&#xff0c;想必大家对聊天软件的功能已经很熟悉&#xff0c; 这里不做过多赘述&#xff0c;笔者通过uniapp实现聊天中的接发消息自动滚动、消息定位和回到底部。 代码实现 <template><view class"chat-container"><!-- 消息列表…

MyBatisMyBatis plus

整合 MyBatis 到 Spring 或 Spring Boot 项目中&#xff0c;可以极大地简化开发流程&#xff0c;尤其是当使用 Spring Boot 时&#xff0c;它提供了自动配置功能&#xff0c;使得集成更加简便。 在 Spring Boot 中整合 MyBatis 1. 添加依赖 首先&#xff0c;在 pom.xml 文件中…

Stable Diffusion 实战-手机壁纸制作 第二篇:优化那些“崩脸”和“马赛克”问题,让图像更加完美!

欢迎回来!在《StableDiffusion实战-手机壁纸制作》系列的第一篇中,我们成功完成了基础操作,制作出了令人炫目的手机壁纸。 今天,我们将进入一个更高阶的领域——优化处理。因为谁不想让生成的艺术品更完美呢?尤其是避免“崩脸”和“马赛克”这种让人抓狂的问题! 创作的路…

408第一季 - 数据结构 - B树与B+树

B树 性质 可以看见一个节点可以有多个数字了 然后也满足左小右大的特征 然后所有的叶子节点都在同一层&#xff0c;然后2个数字的节点就可以有3个分支 然后呢&#xff0c;每个节点里面到底有几个数字是有规定的公式的 就这个公式&#xff0c;m是5阶的&#xff0c;算出来是2和…

SSRF5 Gopher 协议对内网 Web 服务进行 sql 注入 GET 类型和POST类型

实验环境&#xff1b; Centos7.6上同时安装sqli-lib和pikachu 一.Gopher 协议对内网 Web 服务进行 sql 注入 GET 类型 我们先访问sqli-lib第1关 然后我们构造URL&#xff1a; http://192.168.112.12/pikachu-master/vul/ssrf/ssrf_curl.php?urlhttp://192.168.112.12/sql…

Python打卡DAY31

DAY31&#xff1a;文件的规范拆分和写法 恩师浙大疏锦行 知识点&#xff1a; 规范的文件命名规范的文件夹管理机器学习项目的拆分编码格式和类型注解 一、机器学习项目流程&#xff1a; 1、数据加载&#xff1a;从文件、数据库、API 等获取原始数据。 - 命名参考&#xff1a;…

字符串大数 -减法

描述 以字符串的形式读入两个数字&#xff0c;编写一个函数计算它们的和&#xff0c;以字符串形式返回。 代码实现 大小判断&#xff1a;a - b 与 b - a 的绝对值相等将大的数放前面&#xff0c;抽离出结果的符号 import random s, t str(random.randint(1000, 9999)), s…

android google tts如何不联网内部预置多国语音包

在内置Google GMS服务的设备中&#xff0c;可以正常使用TTS&#xff0c;并且可以联网下载多国的语音包。然而&#xff0c;对于未通过GMS认证&#xff0c;只能使用基础的TTS英语播报&#xff0c;而且联网后是无法下载语音包的&#xff0c;会提示需要google service。本文基于以上…

Java 全栈开发学习:从后端基石到前端灵动的成长之路

目录 一、开篇&#xff1a;与 Java 全栈的初遇 二、后端学习&#xff1a;SpringBoot 构建稳健基石 &#xff08;一&#xff09;SpringBoot3 入门&#xff1a;简约而不简单的启程 &#xff08;二&#xff09;Spring Boot Web 应用开发&#xff1a;构建交互桥梁 &#xff08;…

AquaCrop模型源代码分析、模型优化与敏感性分析、未来气候变化影响分析

AquaCrop是由世界粮食及农业组织&#xff08;FAO&#xff09;开发的一个先进模型&#xff0c;旨在研究和优化农作物的水分生产效率。这个模型在全球范围内被广泛应用于农业水管理&#xff0c;特别是在制定农作物灌溉计划和应对水资源限制方面显示出其强大的实用性。AquaCrop 不…

开源模型应用落地-让AI更懂你的每一次交互-mem0-QDrant-Streamlit(一)

一、前言 在人工智能迅猛发展的今天,大型语言模型(LLM)已经成为各行各业的重要工具。然而,尽管这些模型在生成文本、理解语义等方面表现出色,但它们仍然面临一个关键挑战——缺乏持久的记忆能力。传统的对话系统往往只能基于当前对话轮次进行回应,无法有效保留和利用历史…

RPC - Response模块

Requestor 类是一个请求-响应管理器&#xff0c;负责发送请求并处理响应&#xff0c;支持三种交互模式&#xff1a;同步、异步和回调。它跟踪所有发出的请求&#xff0c;当响应到达时将其匹配到对应的请求并进行处理。 newDescribe 函数解析 newDescribe 函数负责创建和注册一…

超高速10G采集卡

超高速10G采集卡是一款高端14位数据采集平台&#xff0c;旨在满足最具挑战性的测量环境。 特性: 单通道和双通道操作 单通道10GSPS或双通道5GSPS 7 GByte/s持续数据传输速率开放式FPGA支持实时DSP 脉冲检测固件选项波形平均固件选项 特征 单通道和双通道工作模式双通道5G…

One-Hot、BOW、TF-IDF、N-Gram区别

1. One-Hot Encoding (独热编码) 核心思想&#xff1a; 为语料库&#xff08;所有文档的集合&#xff09;中的每个唯一单词创建一个维度。对于一个特定的单词&#xff0c;在其对应的维度上标记为1&#xff0c;在所有其他维度上标记为0。 表示&#xff1a; 一个非常长的二进制向…