C++|多态性与虚函数(1)功能绑定|向上转换类型|虚函数

目录

什么是多态性?

概念

分类

向上类型转换

功能的早绑定和晚绑定

绑定

绑定与多态的联系

编译时多态(功能的早绑定)

运行时多态(功能的晚绑定)

一般而言

实现功能晚绑定——虚函数

虚函数定义的说明


什么是多态性?

概念

书上的表示是——向不同的对象发送同一个消息,不同的对象在接受时会有不同的反应,产生不同的动作。

我们在上课时,老师是这么解释的:在一个学校里,每个人都有不同的工作,当校长发出号令“开工”,每个人就开始工作(属于自己的那份工作)。

具体一点:多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,从而可以使用相同的口令来调用相应函数——一个接口,多个方法。

分类

多态性可以分为——参数多态,包含多态,重载多态,强制多态。

参数多态:函数模板,类模板

由函数模板实例化的各个函数具有相同的操作,而这些函数的参数类型却各不相同

由类模板实例化的各个类具有相同的操作,而操作对象的类型各不相同

包含多态定义于不同类之间的同名成员函数,主要通过虚函数来实现。

重载多态:函数重载,运算符重载

函数重载有就是在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数、类型、类型顺序)不同。

运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型时导致不同的行为。 

强制多态:是指将一个变元的类型加以变化,以符合一个函数(或者操作)的要求

如加法运算符在进行浮点数于整形数相加时,首先进行类型强制转换。把整型数变为浮点数再相加的情况。

向上类型转换

向上类型转换就是把一个派生类对象当成基类对象来用 

注意:

向上类型转换是安全的

向上类型转换可以自动完成

向上类型转换的过程会丢失子类信息

#include<iostream>
using namespace std;class point
{
public:point(double a, double b):x(a), y(b){}void area(void){cout << "point:" << 0 << endl;}double x;double y;};class rectangle:public point
{
public:rectangle(double a,double b,double c,double d):point(a,b),x1(c),y1(d){}void area(void){cout << "rectangle:" << (x-x1)*(y-y1)<< endl;}private:double x1;double y1;
};class circle :public point
{
public:circle(double a,double b,double c):point(a,b),r(c){}void area(void){cout << "circle:" <<r*r*3.14<< endl;}
private:double r;
};void calcarea(point& p)
{p.area();
}int main(void)
{point p(0, 0);rectangle r(0, 0, 1, 1);circle c(0, 0, 1);cout << "直接调用:" << endl;p.area();r.area();c.area();cout << "通过calearea函数调用:" << endl;calcarea(p);calcarea(r);calcarea(c);return 0;
}

再caleare函数中,接受point的对象,但也不拒绝point的派生类对象,无需类型转换就可以将rectangle和circle的对象传给calearea。这也就是向上类型转换,可以将派生类转换为基类,这也导致rectangle和circle类的接口变窄。

可以看到通过calearea函数调用时,输出的全是“point:0",显然不是我们希望可看到的,我们希望通过基类的引用直接调用到相应的派生类成员函数。 

也就是当calearea函数中的对象是rectangle时调用rectangle中的area函数;

当calearea函数中的对象时circle的对象时调用cricle中的area函数。

为了解决这个问题需要了解功能的早绑定和晚绑定

功能的早绑定和晚绑定

绑定

确定操作具体对象的过程称为绑定。

绑定是指计算机程序自身彼此关联的过程,把一个标识符和一个存储地址联系在一起(把一条消息和一个对象的方法相结合的过程)。

绑定与多态的联系

按照绑定进行的阶段不同分为:功能的早绑定和功能的晚绑定

多态从实现的角度可以分为:编译时多态和运行时多态

两种绑定方法分别对应多态的两种实现方式

编译时多态(功能的早绑定)

编译过程中确定了同名操作的具体操作对象,在程序执行前期,系统就可以确定同名标识要调用那一段程序代码。

有些多态类型(重载多态,强制多态,参数多态)可以通过早绑定确定同名操作的具体操作对象

运行时多态(功能的晚绑定)

程序运行过程中动态的确定操作所针对的具体对象,在编译过程中无法解决绑定问题,等程序开始运行之后再来确定,包含多态就是通过晚绑定来确定具体操作对象的。

一般而言

编译型语言(C,PASCAL)都采用功能的早绑定,

解释型语言(LISP,Prolog)都采用晚绑定

早绑定具有函数调用速度快,效率高,但缺乏灵活性,晚绑定恰恰相反。

C++由C语言发展而来,为了保持C语言的高效性,C++仍采用编译型也就是早绑定,为了解决某些特定情况,发明了虚函数,让C++可部分采用功能的晚绑定。
C++中,编译时的多态性主要通过函数重载和运算符重载实现。运行时的多态主要通过虚函数来实现。

实现功能晚绑定——虚函数

虚函数提供了一种更为灵活的多态性机制。虚函数允许函数调用与函数体之间的联系在运行时才建立,也就是在运行时才决定同名操作的具体操作对象

虚函数的定义和作用

虚函数定义在基类定义,在成员函数声明前加上virtual,定义语法如下:

virtual 函数类型 函数名(形参表)

{
        函数体;

}

在基类中定义虚函数,

在派生类中重写虚函数,重写时必须满足同名,同参数,同返回值。

使用时必须通过指针或者引用来调用

上面的例子基类时point,修改:我们只需要将point类中的area函数前面加上virtual就可以达到想要的效果。

class point
{
public:point(double a, double b):x(a), y(b){}virtual void area(void){cout << "point:" << 0 << endl;}double x;double y;};

上面的代码是通过引用调用的,下面我们用指针来调用 ,也就是形参为指针,实参传地址。具体代码如下:

void calcarea(point* p)
{p->area();
}int main(void)
{point p(0, 0);rectangle r(0, 0, 1, 1);circle c(0, 0, 1);cout << "直接调用:" << endl;p.area();r.area();c.area();cout << "通过calearea函数调用:" << endl;calcarea(&p);calcarea(&r);calcarea(&c);return 0;
}

虚函数定义的说明

1.派生类应该从它的基类公有派生

2.必须先在基类中定义虚函数(并不一定是最高层的基类)

3.在派生类中重写虚函数是virtual可以写也可以不写

4.一个虚函数无论被继承多少次,都保持其虚函数特性

5.虚函数必须在其类的成员函数中,不能是友元函数,不能是静态成员函数

6.内联函数不能是虚函数

7.构造函数不能是虚函数

8.析构函数可以是虚函数

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

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

相关文章

springboot jar包下config logback外配置文件不生效

描述 与jar 包同级的config目录下放置配置文件 检查1 确定配置配置文件名称为logback-spring.xml 检查2 确定logback-spring.xml 内容正确 检查3 开发环境为 生产环境&#xff08;外配置环境下&#xff09;

寻求发展+兼顾陪读|企业高管赴美国乔治梅森大学做访问学者

E经理拟去美国访学&#xff0c;想达到3个目的&#xff1a;结合本专业方向&#xff0c;扩展至跨学科研究领域&#xff1b;考察市场&#xff0c;寻求新的发展契机&#xff1b;携孩子出国读书&#xff0c;兼顾陪读&#xff0c;并希望尽早出国。最终我们为其落实的乔治梅森大学访问…

会员网站如何创建具有不同仪表盘结构的用户帐户页面

用户帐户页面是中央用户仪表盘&#xff0c;用户可以在其中添加和编辑信息、发布和编辑帖子以及保存收藏夹项目。本教程介绍如何使用“内容”和“重写”模板模式设置帐户页面、为帐户页面创建子页面以及设置个人资料菜单等。 在本教程中&#xff0c;我们将介绍如何使用招聘网站…

PSAI超强插件来袭:一键提升设计效率!

无需魔法&#xff0c;直接在PS中完成图生图、局部重绘、线稿上色、无损放大、扩图等操作。无论你是Windows还是Mac用户&#xff0c;都能轻松驾驭这款强大的AI绘图工具&#xff0c;这款PSAI插件让你的设计工作直接起飞&#xff01; 在之前的分享中&#xff0c;我为大家推荐过两…

Wiley数据库文献哪里比较全?去哪里下载比较高效

Wiley出版社1807年创建于美国&#xff0c;是一家具有超过200年历史的全球知名的出版机构&#xff0c;面向专业人士、科研人员、教育工作者、学生、终身学习者提供必需的知识和服务。 Wiley及旗下的子品牌出版了超过500位诺贝尔奖得主的作品。Wiley Online Library为全学科期刊全…

价格战开卷!字节发布豆包大模型,比行业便宜99.3%

豆包大模型正式亮相 5月15日&#xff0c;在2024春季火山引擎Force原动力大会上&#xff0c;字节跳动自研豆包大模型正式亮相。 &#xff08;图源&#xff1a;证券时报&#xff09; 火山引擎是字节跳动旗下云服务平台&#xff0c;据火山引擎总裁谭待介绍&#xff0c;豆包大模型…

海外媒体发稿:如何在日本媒体投放新闻通稿-大舍传媒

导言 在全球化的时代背景下&#xff0c;海外媒体宣发对于企业来说非常重要。通过在海外媒体投放新闻通稿&#xff0c;企业能够拓展海外市场&#xff0c;增强知名度和影响力。本文将探讨如何在海外媒体投放新闻通稿&#xff0c;以帮助企业进行有效的海外宣传。 挖掘海外媒体资…

Dubbo2.x迁移3.x过程及原理

Dubbo2.x迁移3.x过程及原理 1.Dubbo2.x迁移3.x1.1 快速升级步骤1.2 Provider 端升级过程详解1.2.1 双注册带来的资源消耗 1.3 Consumer 端升级过程1.3.1 APPLICATION_FIRST策略1.3.2 双订阅带来的资源消耗1.3.3 消费端更细粒度的控制 1.4 迁移状态的收敛1.4.1 不同的升级策略影…

Java—如何判断两个浮点数相等

结论 一旦有浮点型数据参与运算的结果&#xff0c;一定不要使用 “ ” 与其比较。 提出问题 我们知道在Java中浮点数float 和 double 的值不能很精准的表示一个小数&#xff0c;因为会有精度损失。 下面来看一个例子&#xff1a; public class FloatTest {public static …

戒烟网站|基于SSM+vue的戒烟网站系统的设计与实现(源码+数据库+文档)

戒烟网站 目录 基于SSM&#xff0b;vue的戒烟网站系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1网站功能模块 2管理员功能模块 3用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主…

使用单目相机前后帧特征点匹配进行3D深度估计的方法

在计算机视觉和机器人领域&#xff0c;三维空间感知是实现环境理解和交互的核心技术之一。特别是在资源受限的场合&#xff0c;使用针孔模型的单目相机进行深度估计成为了一种既经济又实用的解决方案。单目深度估计技术依赖于从连续视频帧中提取和匹配特征点&#xff0c;以估计…

理解JavaScript递归

什么是递归 程序调用自身的编程技巧称为递归&#xff08;recursion&#xff09; 递归的基本思想是将一个复杂的问题分解成更小、更易于管理的子问题&#xff0c;这些子问题与原始问题相似&#xff0c;但规模更小。 递归的要素 基本情况&#xff08;Base Case&#xff09;&…

2024年第十届中西部外语翻译大赛

2024年第十届中西部外语翻译大赛 竞赛信息 “由中西部翻译协会共同体指导发起&#xff0c;各省市译协共建学术指导委员会&#xff0c;2024年第十届中西部外语翻译大赛由中西部翻译协会共同体秘书处&#xff08;武汉公仪网络科技有限公司&#xff09;承办。” - 获奖证书样图 -…

开发板连接电机,烧坏芯片的原因、解决

当使用开发板、核心板&#xff0c;连接电机驱动板&#xff0c;控制电机的转动&#xff0c;会很容易烧芯片。 极少数是通电就烧坏&#xff0c;有些是调试了一段时间才烧&#xff0c;也有些是稳定运行好些日子突然烧了...... 百度搜索&#xff1a;“STM32 电机 烧坏”&#xff…

python文件操作常用方法(读写txt、xlsx、CSV、和json文件)

引言 用代码做分析的时候经常需要保存中间成果&#xff0c;保存文件格式各不相同&#xff0c;在这里好好总结一下关于python文件操作的方法和注意事项 Python 提供了丰富的文件操作功能&#xff0c;允许我们创建、读取、更新和删除文件。允许程序与外部世界进行交互。 文章目录…

【C++】从零开始构建二叉搜索树

送给大家一句话&#xff1a; 我们始终有选择的自由。选错了&#xff0c;只要真诚的反思&#xff0c;真诚面对&#xff0c;也随时有机会修正错误和选择。 – 《奇迹男孩(电影)》 &#x1f4bb;&#x1f4bb;&#x1f4bb;&#x1f4bb;&#x1f4bb;&#x1f4bb;&#x1f4bb;…

数据资源入表难在哪?今晚带你一一弄懂(文末有福利)

​本周&#xff0c;我们即将开启数据要素系列直播《星光对话》的第四期&#xff0c;将由讲师-星光数智首席数据架构师 魏战松&#xff0c;于今晚19:00带来《数据资源入表和运营路径》的主题分享。 精彩内容提前知&#xff1a; 1、入表流程及各阶段参与方 2、入表难点和注意事项…

Android中使用Palette让你的页面UI优雅起来

文章目录 1. 什么是Palette2. 引入Palette3. 使用 Palette3.1 同步方式3.2 异步方式3.3 获取色调值 4. 举例4.1 布局文件 activity_palette_list.xml ⬇️4.2 Activity&#xff1a;PaletteListActivity⬇️4.3 列表Adapter&#xff1a;PaletteListAdapter ⬇️4.4 列表item布局…

「Python绘图」绘制同心圆

python 绘制同心圆 一、预期结果 二、核心代码 import turtle print("开始绘制同心圆") # 创建Turtle对象 pen turtle.Turtle() pen.shape("turtle") # 移动画笔到居中位置 pen.pensize(2) #设置外花边的大小 # 设置填充颜色 pen.fillcolor("green&…

java 并发线程应用

java 并发线程相关 线程状态 新建(NEW): 创建后尚未启动。可运行(RUNABLE): 正在 Java 虚拟机中运行。但是在操作系统层面,它可能处于运行状态,也可能等待资源调度(例如处理器资源),资源调度完成就进入运行状态。所以该状态的可运行是指可以被运行,具体有没有运行要看底层…