C++多态(全)

news2024/12/28 20:37:32

多态

概念

调用函数的多种形态,

多态构成条件

1)父子类完成虚函数的重写(三同:函数名,参数,返回值相同)

2)父类的指针或者引用调用虚函数

虚函数

被virtual修饰的类成员函数

注意

1)只有类的非静态成员函数前才可以加上virtual 

2)虚函数的virtual与虚继承的virtual是同一个关键字。虚函数中的virtual是为了实现多态,虚继承的virtual是为了菱形继承中数据冗余和二义性。

虚函数的重写

也叫虚函数的覆盖

派生类中有一个完全相同的虚函数(返回值类型相同,函数名相同,参数列表相同),就叫做派生类的虚函数重写了基类的虚函数

结果:通过父类Person的指针或引用调用虚函数

父类指针要是指向父类对象则调用父类的虚函数

要是指向子类对象则调用子类虚函数

#include<iostream>
using namespace std;
class Person
{
public:
	virtual void BuyTicket()
	{
		cout << "买票半价" << endl;
	}
};
class Student :public Person
{
public:
	virtual void BuyTicket()
	{
		cout << "买票半价" << endl;
	}
};
void Func(Person& people)
{
	people.BuyTicket();
}
int main()
{
	Student s;

	Func(s);
	return 0;
}
注意

1)派生类的虚函数可以不用加上virtual关键字(不规范,建议加上)

虚函数的两个例外

1)协变

基类和派生类的返回值不同

当基类虚函数返回基类对象的指针或引用

派生类虚函数返回派生类对象的指针或引用

#include<iostream>
using namespace std;

//基类
class A
{};
//子类
class B : public A
{};
//基类
class Person
{
public:
	//返回基类A的指针
	virtual A* fun()
	{
		cout << "A* Person::f()" << endl;
		return new A;
	}
};
//子类
class Student : public Person
{
public:
	//返回子类B的指针
	virtual B* fun()
	{
		cout << "B* Student::f()" << endl;
		return new B;
	}
};
void Func(Person& p)
{
	p.fun();
}
int main()
{
	Student s;

	Func(s);
	return 0;
}

2)析构函数的重写

基类和派生类的析构函数名字不同

当基类的析构函数是虚函数,只要派生类析构函数定义,就构成重写

作用:

要是没有重写,指向子类的指针只会调用父类的析构函数,有可能造成内存泄漏

推荐:

一般把父类的析构函数写成虚函数,反之发生内存泄漏

注意:

在继承中,子类和父类的析构函数会构成隐藏就是因为,虽然子类析构函数和父类的析构函数函数名虽然不同,但是为了构成重写,编译后的析构函数名字会统一处理为destructor();

void test2()
{
	Person* p1 = new Person;
	Person* p2 = new Student;
	delete p1;
	delete p2;
	//本来希望指向父类的指针析构父类
	//指向子类的指针去析构子类
	//因此需要虚函数,构成重写
}

c++11

1)override:检查派生类虚函数是否重写了基类的某个虚函数,没有则编译错误

//子类
class Student : public Person
{
public:
	//子类完成了父类虚函数的重写,编译通过
	virtual void BuyTicket() override
	{
		cout << "买票-半价" << endl;
	}
};

2)final:修饰虚函数,表示该虚函数不能再重写

//父类
class Person
{
public:
	//被final修饰,该虚函数不能再被重写
	virtual void BuyTicket() final
	{
		cout << "买票-全价" << endl;
	}
};

易错例题

纯虚函数

在虚函数后面写上=0

抽象类(接口类):包含纯虚函数的类

特点

1)抽象类不能实例化对象

2)强制派生类重写虚函数(不重写则会继承纯虚函数,又变为抽象类了又不能实例化对象了)

3)用抽象类(父类)的指针调用虚函数

作用

1)抽象类能更好的

#include <iostream>
using namespace std;
//抽象类(接口类)
class Car
{
public:
	//纯虚函数
	virtual void Drive() = 0;
};
int main()
{
	Car c; //抽象类不能实例化出对象,error
	return 0;
}

#include <iostream>
using namespace std;
//抽象类(接口类)
class Car
{
public:
	//纯虚函数
	virtual void Drive() = 0;
};
//派生类
class Benz : public Car
{
public:
	//重写纯虚函数
	virtual void Drive()
	{
		cout << "Benz-舒适" << endl;
	}
};
//派生类
class BMV : public Car
{
public:
	//重写纯虚函数
	virtual void Drive()
	{
		cout << "BMV-操控" << endl;
	}
};
int main()
{
	//派生类重写了纯虚函数,可以实例化出对象
	Benz b1;
	BMV b2;
	//不同对象用基类指针调用Drive函数,完成不同的行为
	Car* p1 = &b1;
	Car* p2 = &b2;
	p1->Drive();  //Benz-舒适
	p2->Drive();  //BMV-操控
	return 0;
}

抽象类作用

1)用来表达没有实例对象的抽象类型

2)强制子类重写虚函数(同override)

原理

多态调用:运行时,到指向对象的虚表中找虚函数调用

普通调用:编译时,调用的对象是那个类型就调用它的函数

虚表:虚函数表,存虚函数的地址,目标实现多态

虚基表:存的是当前位置距离虚基类部分的偏移量,解决菱形继承和二义性的问题

虚函数和普通函数一样:在代码段中,不是在虚表中的(虚表内的是虚函数的地址

虚表在常量区

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

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

相关文章

Systemback Ubuntu14.04 制作自定义系统ISO镜像

工作需要&#xff0c;要基于ubuntu自定义一些编译环境并将自己配置好的ubuntu做成镜像。 硬件准备 ​ 为保证能够顺利完成系统iso镜像的制作与系统还原&#xff0c;推荐准备一个较大容量的U盘或者移动固态硬盘&#xff0c;同时确保自己的Ubuntu系统还有比较大的可用空间。 1 S…

Maven入门:1.简介与环境搭建

一.简介与环境搭建 1.Maven&#xff1a;用于自动化构建项目&#xff08;按照企业主流模板构建完善的项目结构&#xff09;和管理项目依赖&#xff08;依赖就是项目的jar包&#xff0c;通过配置的方式进行添加和管理&#xff0c;自动下载和导入&#xff09;的工具。即更加方便构…

监视器和显示器的区别,普通硬盘和监控硬盘的区别

监视器与显示器的区别&#xff0c;你真的知道吗&#xff1f; 中小型视频监控系统中&#xff0c;显示系统是最能展现效果的一个重要环节&#xff0c;显示系统的优劣将直接影响视频监控系统的用户体验满意度。 中小型视频监控系统中&#xff0c;显示系统是最能展现效果的一个重要…

CSS 伪类、伪元素的应用实例:电池充电、高能进度条

一、目的 本文通过 CSS 伪类、伪元素&#xff0c;结合动画 animation 和 Vue 动态样式属性&#xff08;通过 CSS 变量&#xff09;的写法&#xff0c;来实现电池充电、高能进度条的效果&#xff0c;如下图所示。 二、基础知识 1、CSS 伪类、伪元素 简单概括成以下 4 点&#x…

JavaScript转换和校验数字

本节我们使用的案例还是继续之前的银行家应用程序&#xff0c;只不过我们呢增加了两个账号&#xff0c;代码如下&#xff1a; const account1 {owner: Jonas Schmedtmann,movements: [200, 455.23, -306.5, 25000, -642.21, -133.9, 79.97, 1300],interestRate: 1.2, // %pin…

Macos安装OrbStack

什么是OrbStack OrbStack 是一种在 macOS 上运行容器和 Linux 机器的快速、轻便和简单方法。它是 Docker Desktop 和 WSL 的超强替代品&#xff0c;所有这些都在一个易于使用的应用程序中。 在Macos M系列芯片上&#xff0c;经常遇到docker镜像不兼容的问题&#xff0c;此时使…

Git客户端(TortoiseGit)使用详解

1.概述 使用TortoiseGit比直接使用git 客户端和命令实现代码版本管理更为方便&#xff0c;本文根据实际使用情况作一些记录&#xff0c;特别是对于解决冲突的处理。 2.Git安装与配置 下载 Git - Downloads&#xff0c; 可参考Git安装步骤完成Git的安装与配置。 3.TortoiseG…

【最大公约数 排序】2344. 使数组可以被整除的最少删除次数

本文涉及知识点 最大公约数 排序 LeetCode2344. 使数组可以被整除的最少删除次数 给你两个正整数数组 nums 和 numsDivide 。你可以从 nums 中删除任意数目的元素。 请你返回使 nums 中 最小 元素可以整除 numsDivide 中所有元素的 最少 删除次数。如果无法得到这样的元素&a…

Java设计模式 _结构型模式_组合模式

一、组合模式 1、组合模式 组合模式&#xff08;Composite Pattern&#xff09;是这一种结构型设计模式。又叫部分整体模式。组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次关系。即&#xff1a;创建了一个包含自己对象组的类&#xff0c;该类提供了修改…

校园二手|基于SprinBoot+vue的微信小程序的校园二手平台(源码+数据库+文档)

校园二手平目录 目录 基于SprinBootvue的微信小程序的校园二手平台 一、前言 二、系统设计 三、系统功能设计 1搜索功能、分类功能测试 2商品购买功能测试 3用户注册功能测试 4商品信息管理功能测试 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设…

【网站项目】木里风景文化管理平台

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

电脑装了两个Win10系统,怎么修改其名称方便识别?

前言 有小伙伴在上一期的双系统教程上留言说怎么修改双系统引导时候显示的名称 不然看起来两个系统好像都没啥分别&#xff0c;如果是Windows10Windows11的方案还好说&#xff0c;但如果是两个Windows10或者是两个Windows11&#xff0c;有时候还真的很不好分辨。 万一想要启动…

【stomp 实战】Spring websocket 用户订阅和会话的管理源码分析

通过Spring websocket 用户校验和业务会话绑定我们学会了如何将业务会话绑定到spring websocket会话上。通过这一节&#xff0c;我们来分析一下会话和订阅的实现 用户会话的数据结构 SessionInfo 用户会话 用户会话定义如下&#xff1a; private static final class Sessio…

第三节课,功能2:开发后端用户的管理接口-- postman--debug测试

一、如何使用postman 网址&#xff1a; https://www.postman.com/downloads/ 【Postman小白教程】五分钟学会如何使用Postman~_哔哩哔哩_bilibili postman安装使用_bowser agent在postman哪里-CSDN博客 二、下载后 登录&#xff0c;开始测试 2.1 关于postman 报错&#…

IOT-9608I-L 的GPIO应用

目录 概述 1 GPIO接口介绍 2 板卡上操作IO 2.1 查看IO驱动 2.2 使用ECHO操作IO 2.2.1 端口选择 2.2.2 查看IO 2.2.3 echo操作IO 3 C语言实现一个操作IO的案例 3.1 功能介绍 3.2 代码实现 3.3 详细代码 4 测试 测试视频地址&#xff1a; IOT-9608I-L的一个简单测试&a…

探索APP分发的新趋势 - 内容包括小猪APP分发平

APP分发探索APP分发的新趋势 - 内容包括小猪APP分发平台的重要性 APP分发是移动互联网的核心环节探索APP分发的新趋势 - 内容包括小猪APP分发平台&#xff0c;它链接探索APP分发的新趋势 - 内容包括小猪APP分发平台了开发者和用户探索APP分发的新趋势 - 内容包括小猪APP分发平…

区块链 | 由外部实体导致的 NFT 安全问题

&#x1f98a;原文&#xff1a; Understanding Security Issues in the NFT Ecosystem &#x1f98a;警告&#xff1a; 本文只记录了原文的第 6 节。 1 问题描述 NFT 所指向的数字资产&#xff08;图片、视频等&#xff09;必须是可以访问的&#xff0c;这样 NFT 才具有意义…

牛客网刷题 | BC70 计算单位阶跃函数

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 KiKi最近学习了信号…

慧言AIVoceChat实现在线客服及社区频道

原文链接&#xff1a;小回博客 慧言AI&VoceChat实现在线客服及社区频道 一、VoceChat 简介 官网&#xff1a;https://voce.chat VoceChat 是一款支持独立部署的个人云社交媒体聊天服务。15MB 的大小可部署在任何的服务器上&#xff0c;部署简单&#xff0c;很少需要维护…

VS2022 .Net6.0 无法打开窗体设计器

拿Vs2022 建了个Demo&#xff0c;运行环境是net6.0-windows&#xff0c;无论双击或是右键都打不开窗体设计器 打开项目目录下的*.csproj.user <?xml version"1.0" encoding"utf-8"?> <Project ToolsVersion"Current" xmlns"htt…