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

news2024/11/17 3:23:23

目录

什么是多态性?

概念

分类

向上类型转换

功能的早绑定和晚绑定

绑定

绑定与多态的联系

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

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

一般而言

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

虚函数定义的说明


什么是多态性?

概念

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

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

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

分类

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

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

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

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

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

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

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

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

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

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

向上类型转换

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

注意:

向上类型转换是安全的

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

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

#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.coloradmin.cn/o/1676404.html

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

相关文章

CSS表格特殊样式

列组样式 使用colgroup与col标签配合可以定义列祖样式&#xff1a;例 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>table,tr,th,td{border: 1px solid #000;}table{border-collapse: coll…

Meilisearch使用过程趟过的坑

Elasticsearch 做为老牌搜索引擎&#xff0c;功能基本满足&#xff0c;但复杂&#xff0c;重量级&#xff0c;适合大数据量。 MeiliSearch 设计目标针对数据在 500GB 左右的搜索需求&#xff0c;极快&#xff0c;单文件&#xff0c;超轻量。 所以&#xff0c;对于中小型项目来说…

基于SVPWM控制策略的二极管钳位型NPC逆变器并网闭环simulink仿真

本人搭建了基于SVPWM控制策略的二极管钳位型NPC逆变器并网闭环的simulink仿真模型&#xff0c;该模型采用SVPWM闭环控制实现并网控制。效果优异&#xff0c;配备参考资料&#xff0c;适合新手学习使用。 DC&#xff1a;800V AC:380V 功率&#xff1a;100kw 拓扑&#xff1a;…

fastjson_1.2.24和Shiro(CVE-2016-4437)漏洞复现

文章目录 一、fastjson 1.2.24远程命令执行漏洞复现二、shiro反序列化漏洞(CVE-2016-4437)1、Shiro漏洞原理2、手工验证漏洞3、使用ShiroAttack2 一、fastjson 1.2.24远程命令执行漏洞复现 配置环境&#xff1a;本机java 8环境 kali操作系统&#xff08;java8&#xff09; c…

如果你想学习大数据,那么你应该看看这些高分佳作

大家好&#xff0c;我是王有志&#xff0c;一个分享硬核 Java 技术的金融摸鱼侠&#xff0c;欢迎大家加入 Java人自己的交流群“共同富裕的 Java 人”。 今天和大家分享的主题是&#xff1a;大数据入门书籍。公众号内回复关键字&#xff1a;20240515&#xff0c;即可获取。 &a…

【正版系统】海外短剧系统功能介绍,前端uniapp+开源。

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、海外短剧系统功能介绍 二、搭建要求 1.系统要求 总结 前言 短剧作为一种快速、紧凑的娱乐形式&#xff0c;正逐渐受到更多海外观众的喜爱。这种需求增长为…

基于RTL8710BN与天猫精灵的WIFI智能家居方案

0 项目简介 目的&#xff1a; 语音控制智能家居产品 基于阿里云的物联网产品 基于WiFi技术的嵌入式产品 主要技术&#xff1a; WiFi技术 常用的物联网协议 网络编程 云平台配置 MCU OPENSDK开发 阿里物联网操作系统 硬件&#xff1a; wifi开发板RTL8710BN 天猫精灵…

版本控制:软件开发的基石(一文读懂版本控制)

未经允许&#xff0c;禁止转载&#xff01; 在现代软件开发中&#xff0c;版本控制是不可或缺的工具。它帮助开发者跟踪和管理代码的变化&#xff0c;协作完成项目&#xff0c;并确保代码的完整性和安全性。本文将基于Git官网的视频“什么是版本控制”来深入探讨版本控制的基本…

Linux常用指令集合

ls显示目录文件 选项&#xff1a; -a 所有文件&#xff08;all所有&#xff09; -l 详细信息&#xff08;Information信息&#xff09;&#xff08;自动包含-1&#xff09; 所以常用 ll -1 一行只输出一个文件。 -R 列出所有子目录下的文件。…

优雅谈论大模型4:初识Token

Token 在继续前行之前&#xff0c;需要先停下来澄清下Token这个词&#xff0c;以及如何将原始的语料转化为Token&#xff0c;在细究背后的原理之后会更加优雅的理解大模型。任何的资讯都可以生成语料&#xff0c;而这些语料需要被机器理解以及供后续的模型训练&#xff0c;那么…

Nginx配置Referer防盗链

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 HTTP Referer是Hea…

mongodb备份还原指南

MongoDB 提供的命令行实用程序mongodump和mongorestore创建备份和恢复数据的过程。 一、数据备份 mongorestore和mongodump实用程序可处理BSON数据转储&#xff0c;对于创建小型部署的备份非常有用。要实现弹性且无中断的备份&#xff0c;请将文件系统快照或区块级磁盘快照与…

Ubuntu20.04调试功能包的一些报错解决办法【更新中2024.05.14】

一、Could not find a package configuration file provided by “catkin_virtualenv” 解决办法&#xff1a; sudo apt install ros-noetic-catkin-virtualenv二、 ERROR: Could not find a version that satisfies the requirement pip-tools5.1.2 (from versions: none) …

优选算法——双指针2

题目一——有效三角形的个数 思路 先审题 举个例子&#xff0c;下面一个序列可分成4个三元组 然后我们论证哪个可以组成三角形即可 判断三个数能不能组成三角形&#xff1a;任意两边之和大于第三边 注意第一个和第四个&#xff0c;有人说&#xff0c;这不是两个相同的吗&#…

数据结构与算法学习笔记十---链队列的表示和实现(C语言)

目录 前言 1.什么是链队 2.链队的表示和实现 1.定义 2.初始化 3.销毁 4.清空 5.空队列 6.队列长度 7.获取队头 8.入队 9.出队 10.遍历队列 11.完整代码 前言 本篇博客介绍链栈队列的表示和实现。 1.什么是链队 链队是采用链式存储结构实现的队列。通常链队使用单…

AcWing166. 数独-DFS剪枝与优化

题目 思路 思考问题&#xff1a;搜索顺序->考虑剪枝搜索顺序&#xff1a;先随意选择一个空格子&#xff0c;枚举该格子可填写的数字&#xff0c;当所有格子都填完的时候&#xff0c;说明可以退出了剪枝&#xff1a; 优化搜索顺序&#xff1a;随意选择一个空格子&#xff1a…

83.网络游戏逆向分析与漏洞攻防-移动系统分析-游戏瞬移漏洞的测试与分析

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

JSON格式化输出到页面上——数组+对象+JSON字符串+汉字——基础积累

实现功能&#xff1a;将接口返回的内容格式化后展示到页面上。 对象数组——效果图 对象——效果图 汉字——效果图 直接上代码&#xff1a; 解决步骤1&#xff1a;html代码 <div><div class"contentWrp" style"margin-top: 10px"><div …

vue 文本中的\n 、<br>换行显示

一、背景&#xff1a; 后端接口返回数据以\n 作为换行符&#xff0c;前端显示时候需要换行显示&#xff1b; demo&#xff1a; <p style"white-space: pre-wrap;">{{ info }}</p>data() {return {info: 1、优化图片\n 2、 优化时间\n}},项目上&#…

企业内部文化社区究竟有哪些好处?

首先&#xff0c;我们来了解下&#xff0c;企业内耗是什么? 在企业文化管理中&#xff0c;内耗是一个常见的问题&#xff0c;它会影响企业的团队协作、执行效率和绩效表现。在2023《哈佛商业评论》中国年会上&#xff0c;北大汇丰商学院管理实践教授陈玮分享了他对组织管理的…