C++多态性之包含多态(一)—学习记录

news2025/3/19 3:08:11

一、C++的包含多态

        面向对象程序设计的四大特点为抽象、封装、继承和多态,其中,多态性可以提高代码的可拓展性和可维护性

        多态是指同样的消息被不同类型的对象接收时导致不同的行为。所谓消息是指对类的成员函数的调用,不同的行为是指不同的实现,也就是调用了不同的函数[1]。面向对象的多态性可以分为重载多态强制多态包含多态参数多态四类,其中,包含多态是类族中定义于不同类中的同名成员函数的多态行为,本文将基于包含多态进行展开学习。

包含多态的关键学习内容:

1. 虚函数

(1)虚函数是动态绑定的基础,虚函数必须是非静态的成员函数。虚函数声明只能出现在类定义中的函数原型声明中,而不能在成员函数实现的时候。一般虚函数成员的声明语法为:

virtual 函数返回值类型 函数名(形参表);

(2)运行过程中的多态需要满足3个条件,第一是类之间满足赋值兼容规则,第二是要在基类中声明虚函数,第三是要由成员函数来调用或者是通过指针、引用来访问虚函数

(3)如果是使用对象名来访问虚函数,则绑定在编译过程中就可以进行(静态绑定),因为对象的类型是确定不变的。

(4)动态绑定只有通过指针或引用调用虚函数时才会发生。即当且仅当对通过指针或引用调用虚函数时,才会在运行时解析该调用,也只有在这种情况下对象的动态类型才有可能与静态类型不同。

(5)(编程规范)在C++11新标准中,使用override关键字来说明派生类中的虚函数可以使得程序员的意图更加清晰的同时让编译器可以发现一些错误。如果使用override标记了某个函数,但该函数并没有覆盖已存在的虚函数,此时编译器将报错[2]

(6)(编程规范)在C++11新标准中,使用final关键字将函数声明后,任何尝试覆盖该函数的操作都将引发错误[2]

(7)override和final说明符出现在形参列表(包括任何const或引用修饰符)以及尾置返回类型之后。

2. 类型兼容规则

(1)类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。在替代之后,派生类对象就可以作为基类的对象使用,但只能使用从基类继承的成员。

(2)类型兼容规则中所指的替代包括派生类的对象可以隐含转换为基类对象派生类的对象可以初始化基类的引用以及派生类的指针可以隐含转换为基类的指针

补充说明:

1. 派生类覆盖基类的成员函数时,派生类中既可以使用virtual关键字,也可以不显式给出虚函数声明,二者没有差别。若派生类并没有显式给出虚函数声明,这时系统就会遵循以下规则来判断派生类的一个函数成员是否为虚函数,若三个条件同时满足则自动确定为虚函数:

        (1)该函数是否与基类的虚函数有相同的名称;

        (2)该函数是否与基类的虚函数有相同的参数个数及相同的对应参数类型;

        (3)该函数是否与基类的虚函数有相同的返回值或者满足赋值兼容规则的指针、引用型的返回值。

2. 派生类中的虚函数会隐藏基类中同名函数的所有其他重载形式。

3. 在重写继承来的虚函数时,如果函数有默认形参值,不要重新定义不同的值。原因为虚函数是动态绑定的,但默认形参值是静态绑定的。

二、虚析构函数

        在C++中,不能声明虚构造函数,但是可以声明虚析构函数。如果一个类的析构函数是虚函数,那么由它派生而来的所有子类的析构函数也是虚函数。析构函数设置为虚函数之后,在使用指针引用时可以动态绑定,实现运行时的多态,保证使用基类类型的指针就能够调用适当的析构函数针对不同的对象进行清理工作。

虚析构函数的声明语法为:

virtual ~类名();

三、纯虚函数

        纯虚函数是一个在基类中声明的虚函数,它在该基类中没有定义具体的操作内容,要求各派生类根据实际需要给出各自的定义。纯虚函数的声明格式为:

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

注意事项:

如果将析构函数声明为纯虚函数,必须给出它的实现,因为派生类的析构函数体执行完后需要调用基类的纯虚函数。

四、抽象类

        抽象类是一种特殊的类,它为一个类族提供统一的操作界面。抽象类是为了抽象和设计的目的而建立的。抽象类不能实例化,即不能定义一个抽象类的对象,但是可以定义一个抽象类的指针和引用,通过指针或引用就可以指向并访问派生类的对象,进而访问派生类的成员。

        带有纯虚函数的类是抽象类。抽象类的主要作用是通过它为一个类族建立一个公共的接口,使它们能够更有效地发挥多态特性。抽象类声明了一个类族派生类的公共接口,而接口的完整实现,即纯虚函数的函数体,要由派生类自己定义。

五、代码实验

#include <iostream>
#include <math.h>

using namespace std;

// 抽象类
class geometry
{
    public:
        virtual double Area_cal() = 0;
        virtual double Peri_cal() = 0;
        virtual void Area_show() = 0;
        virtual void Peri_show() = 0;
};

// 矩形
class rectangle:public geometry
{
    public:
        rectangle(double w, double h) { width = w; height = h; };
        ~rectangle() {};
        double Area_cal() { return width * height; };
        double Peri_cal() { return 2 * (width + height); };
        void Area_show() { cout << "该矩形的面积:" << Area_cal() << "平方米" << endl; };
        void Peri_show() { cout << "该矩形的周长:"<< Peri_cal() <<"米" << endl; };
        double width;
        double height;
};

// 正方形
class square :public rectangle
{
    public:
        square(double w):rectangle(w,w) {};
        ~square() {};
        double Area_cal() { return pow(width,2); };
        double Peri_cal() { return 4 * width; };
        void Area_show() { cout << "该正方形的面积:" << Area_cal() << "平方米" << endl; };
        void Peri_show() { cout << "该正方形的周长:" << Peri_cal() << "米" << endl; };
};

int main()
{
    square a(2);
    rectangle b(3, 4);
    geometry* aa = &a;
    aa->Area_show();
    aa->Peri_show();
    geometry* bb = &b;
    bb->Area_show();
    bb->Peri_show();
    return 0;
};

参考资料:

[1]  C++语言程序设计 / 郑莉,董渊,何江舟编著.—4版.—北京:清华大学出版社,2010.7(清华大学计算机系列教材)

[2] C++ Primer中文版:第5版 /(美)李普曼(Lippman,S.B.),(美)拉乔伊(Lajoie,J.),(美)默(Moo,B.E.)著;王刚,杨巨峰译. —北京:电子工业出版社,2013.9.

[3] https://www.youtube.com/watch?v=ALGQJHIiZ5U(c++侯捷)

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

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

相关文章

KERL文献阅读分享:知识图谱与预训练语言模型赋能会话推荐系统

标题期刊年份Knowledge Graphs and Pre-trained Language Models enhanced Representation Learning for Conversational Recommender SystemsJournal of LaTeX Class Files2021 &#x1f4c8;研究背景 在数字时代&#xff0c;个性化推荐系统已经成为了我们生活的一部分。从电…

从零开始:使用Jenkins实现高效自动化部署

在这篇文章中我们将深入探讨如何通过Jenkins构建高效的自动化部署流水线&#xff0c;帮助团队实现从代码提交到生产环境部署的全流程自动化。无论你是Jenkins新手还是有一定经验的开发者&#xff0c;这篇文章都会为你提供实用的技巧和最佳实践&#xff0c;助你在项目部署中走得…

hive的几种复杂数据类型

Hive的几种复杂数据类型 Hive 提供了几种复杂数据类型&#xff0c;能够支持更灵活和多样的数据存储。这些复杂数据类型对于处理嵌套数据或不规则数据特别有用。主要包括以下几种&#xff1a; 文章目录 Hive的几种复杂数据类型1. 数组&#xff08;ARRAY&#xff09;2. 结构体&a…

序列化/反序列化与TCP通信协议

深入理解序列化/反序列化与TCP通信协议 一、序列化与反序列化 1.1 基本概念 序列化&#xff08;Serialization&#xff09;: 将数据结构或对象状态转换为可存储/传输格式的过程反序列化&#xff08;Deserialization&#xff09;: 将序列化后的数据恢复为原始数据结构的过程 …

Ollama 本地部署 体验 deepseek

下载安装ollama,选择模型 进行部署 # 管理员命令行 执行 ollama run deepseek-r1:70b浏览器访问http://ip:11434/ 返回 Ollama is runninghttp://ip:11434/v1/models 返回当前部署的模型数据 下载安装CherryStudio&#xff0c;本地对话UI 客户端 在设置中 修改API地址&#x…

Linux探秘坊-------4.进度条小程序

1.缓冲区 #include <stdio.h> int main() {printf("hello bite!");sleep(2);return 0; }执行此代码后&#xff0c;会 先停顿两秒&#xff0c;再打印出hello bite&#xff0c;但是明明打印在sleep前面&#xff0c;为什么会后打印呢&#xff1f; 因为&#xff…

postgreSQL16.6源码安装

1.获取源码 从PostgreSQL: File Browser获取tar.bz2或者tar.gz源码 2.解压 tar xf postgresql-version.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# tar xf postgresql-16.6.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# ll 总计 24324 drwxr-xr-x 12 ro…

树莓派上 基于Opencv 实现人脸检测与人脸识别

一&#xff0c;需求 基于树莓派4b&#xff0c;usb1080p摄像头&#xff0c;实现人脸检测与人脸识别。尝试了海陵科的模组和百度的sdk。海陵科的模组无法录入人脸&#xff0c;浪费了100多块钱。百度的sdk 在树莓派上也无法录入人脸&#xff0c;官方解决不了。最后只能用opencv自…

mac下dify+deepseek部署,实现私人知识库

目前deepseek 十分火爆&#xff0c;本地部署实现私有知识库&#xff0c;帮助自己日常工作&#xff0c;上一篇使用工具cherry studio可以做到私人知识库。今天学习了一下&#xff0c;使用Dify链接deepseek&#xff0c;实现私人知识库&#xff0c;也非常不错&#xff0c;这里分享…

CSS 实现下拉菜单效果实例解析

1. 引言 在 Web 开发过程中&#xff0c;下拉菜单是一种常见且十分实用的交互组件。很多前端教程都提供过简单的下拉菜单示例&#xff0c;本文将以一个简洁的实例为出发点&#xff0c;从 HTML 结构、CSS 样式以及整体交互逻辑三个层面进行详细解析&#xff0c;帮助大家理解纯 C…

x64、aarch64、arm与RISC-V64:详解四种处理器架构

x64、aarch64、arm与RISC-V64:详解四种处理器架构 x64架构aarch64架构ARM架构RISC-V64架构总结与展望在计算机科学领域,处理器架构是构建计算机系统的基石,它决定了计算机如何执行指令、管理内存和处理数据。x64、aarch64、arm与RISC-V64是当前主流的四种处理器架构,它们在…

Java使用aspose实现pdf转word

Java使用aspose实现pdf转word 一、下载aspose-pdf-21.6.jar包【下载地址】&#xff0c;存放目录结构如图&#xff1b;配置pom.xml。 <!--pdf to word--> <dependency><groupId>com.aspose</groupId><artifactId>aspose-pdf</artifactId>…

国产编辑器EverEdit - 迷你查找

1 迷你查找 1.1 应用场景 某些场景下&#xff0c;用户不希望调出复杂的查找对话框&#xff0c;此时可以使用迷你查找窗口。 1.2 使用方法 选择主菜单查找 -> 迷你查找&#xff0c;或使用快捷键Ctrl Alt F&#xff0c;会在右上角弹出迷你查找窗口&#xff0c;如下图所示…

嵌入式音视频开发(一)ffmpeg框架及内核解析

系列文章目录 嵌入式音视频开发&#xff08;零&#xff09;移植ffmpeg及推流测试 嵌入式音视频开发&#xff08;一&#xff09;ffmpeg框架及内核解析 文章目录 系列文章目录前言一、ffmpeg的内核1.1 框架解析1.2 内核解析1.3 FFmpeg内部数据流1.3.1 典型的解码流程1.3.2 典型的…

javaEE-11.javaScript入门

目录 一.什么是javaScript 二.快速实现 三.JS引入方式 1.行内引入: 2.内部引入: 3.外部引入: 四.基础语法 1.变量 变量命名规则: 2.数据类型 3.运算符 五.JS对象 1.数组 创建数组: 2.操作数组 3.函数 函数注意事项: 函数参数: 4.对象 1.使用字面量 创建对象:…

畅游Diffusion数字人(16):由音乐驱动跳舞视频生成

畅游Diffusion数字人(0):专栏文章导航 前言:从Pose到跳舞视频生成的工作非常多,但是还没有直接从音乐驱动生成的工作。最近字节跳动提出了MuseDance,无需复杂的动作引导输入(如姿势或深度序列),从而使不同专业水平的用户都能轻松进行灵活且富有创意的视频生成。 目录 贡…

DeepSeek 助力 Vue 开发:打造丝滑的步骤条

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

领略算法真谛:差分

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…

【图片转换PDF】多个文件夹里图片逐个批量转换成多个pdf软件,子文件夹单独合并转换,子文件夹单独批量转换,基于Py的解决方案

建筑设计公司在项目执行过程中&#xff0c;会产生大量的设计图纸、效果图、实景照片等图片资料。这些资料按照项目名称、阶段、专业等维度存放在多个文件夹和子文件夹中。 操作需求&#xff1a;为了方便内部管理和向客户交付完整的设计方案&#xff0c;公司需要将每个项目文件…

在Linux上如何让ollama在GPU上运行模型

之前一直在 Mac 上使用 ollama 所以没注意&#xff0c;最近在 Ubuntu 上运行发现一直在 CPU 上跑。我一开始以为是超显存了&#xff0c;因为 Mac 上如果超内存的话&#xff0c;那么就只用 CPU&#xff0c;但是我发现 Llama3.2 3B 只占用 3GB&#xff0c;这远没有超。看了一下命…