多态是对于处理不同的变量,但是使用相同或者类似的方式。多态核心分为两种形式:编译时多态(静态多态)和运行时多态(动态多态)C++中多态通常使用虚函数或者指针(引用)实现。

news/2025/9/21 17:23:46/文章来源:https://www.cnblogs.com/ljbguanli/p/19103858

多态是对于处理不同的变量,但是使用相同或者类似的方式。多态核心分为两种形式:编译时多态(静态多态)和运行时多态(动态多态)C++中多态通常使用虚函数或者指针(引用)实现。

多态是对于处理不同的变量,但是使用相同或者类似的方式。

多态主要分为两种形式:编译时多态(静态多态)和运行时多态(动态多态)

C++中多态通常使用虚函数或者指针(引用)实现

静态多态

函数重载

#include
using namespace std;
int main()
{
//同样的函数 但是传入的参数不同
Test();
Test(1);
return 0;
}
void Test() {
}
//函数重载
void Test(int a) {
}
  • 运算符重载

动态多态

虚函数

向上转型

#include
using namespace std;
class Person
{
public:
Person()
{
}
~Person()
{
}
string name = "123";
void Test()
{
cout Test();
p = &t;
p->Test();
return 0;
}

C++中子类的指针对象可以赋值给基类的指针对象是C++支持多态性,这种行为被称为向上转型。因为派生类包含了基类的所有对象,因此可以被视为基类的对象。

这样的向上转型,可以通过基类去调用派生类中与基类相同的函数,但是调用的还是基类Person的函数,想要调用子类的函数,需要在基类函数前添加关键字virtual

virtual void Test()

动态多态通过虚函数和虚函数表实现的,根据对象的实际类型来调用相应的虚函数,而不是根据指针或引用的静态类型。

虚函数表

虚函数的实现依赖于虚函数表,每一个包含虚函数的类都有一个虚函数表,表中存储了虚函数的地址,通过基类调用虚函数时,程序会在运行时查找虚函数表以找到正确的函数地址。

virtual 本质是构造指针以及指针的寻址地址

纯虚函数

//纯虚函数
virtual void Test() = 0;

如果一个类包含了一个纯虚函数,那么这个类就是抽象类

  • 抽象类无法被实例化,只能作为基类去继承
  • 抽象类的虚函数必须由派生类去实现
  • 一个类如果继承多个抽象类,每个抽象类的抽象函数都要被实现

虚析构函数

class Person
{
public:
Person()
{
cout << "Person constructor" << endl;
}
//虚析构函数
virtual ~Person()
{
cout << "Person destructor" << endl;
}
};

栈式调用 堆式调用

#include
using namespace std;
class Person
{
public:
Person()
{
}
~Person()
{
cout Test();
//堆式调用
//这样的调用是否还会调用Student的析构函数?
Person* p1 = new Student;
p1->Test();
delete p1;
return 0;
}

运行之后发现,栈式调用是会调用子类的析构函数的(也就是Student的析构),但是堆式调用时不会调用子类的析构函数的,但是如果不调用,那么就有可能产生内存泄漏。

为了解决这样的问题,我们使用虚析构函数,此时,就能够调用子类的析构函数。

当一个类有虚函数时,通常应该为他提供一个虚析构函数,以确保删除指向派生类对象的基类指针时正确调用析构函数

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

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

相关文章

从 C++ 到 Python

从 C++ 到 Python 一、注释 #单行注释多行注释"""多行注释"""二、字符串 Hello, python! #单、双引号都可以,没有区别 #倾向于用单引号三、I/O与变量 #输出 print(Hello, python!) #Py…

在 Unity 中实现 0GC(零垃圾回收)对象池 — 实战指南 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Nipper 3.9.0 for Windows Linux - 网络设备漏洞评估

Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估 Nipper for routers, switches & firewalls | Nipper Network Configuration Audit Tool 请访…

c++单例实践

这篇文章为大家介绍`static` 关键字相关知识以及如何实现自己的C++单例类。C++单例实践 在日常开发中,虽然太多的单例调用会让代码的耦合度变高,但是例如日志类这种,单例模式就变得非常有。所以这篇文章为大家介绍s…

NOIP 模拟赛九

gcd+DP+数据结构/贪心+整体 DPReverse Card \((a+b)\mid b\cdot \gcd(a, b)\) 计数。 先化式子,记 \(g=\gcd(a, b), a=ag, b=bg\) 。 \(g(a+b)\mid g^2b\) ,即 \((a+b)\mid gb\) 。 又 \(\gcd(a + b, b)=\gcd(a, b) …

个人项目-软件工程第二次作业 - Nyanya-

这个作业属于哪个课程 计科23级34班这个作业要求在哪里 个人项目这个作业的目标 进行个人编程,设计论文查重算法Github仓库 https://github.com/username/PaperCheck一、PSP表格PSP2.1 Personal Software Process Sta…

go语言中的复杂数据类型

go语言中的复杂数据类型package mainimport ("fmt" )func main() {// 基本类型var a int = 10var b float64 = 3.14var c bool = truevar d byte = Avar e rune = 中var f string = "Hello, Go!"v…

详细介绍:互联网医院品牌IP的用户体验和生态构建

详细介绍:互联网医院品牌IP的用户体验和生态构建pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas",…

实用指南:认知语义学中的象似性对人工智能自然语言处理深层语义分析的影响与启示

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

支持 SSL 中等强度密码组(SWEET32) - 漏洞检查与修复

突发奇想,把漏洞修复的事情也记录一个文档,之前也修复过很多的漏洞,但是总是修复了就完事了,没有留存记录,以后的漏洞我会留一个tag专门记录,如果正好其他人也有遇到的这样的问题,可以很快速的有一个处理方向和…

C# WPF CommunityToolkit.MVVM (测试一)

MainWindow.xaml<Window x:Class="CommunityToolkit.MVVM_RelayCommand_测试.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.m…

linux kernel synchronization rcu

Read Copy Update /RCU 可以单个写,多个读,在内核中常用于更新链表。对比顺序锁,只能用指针访问资源,读数据无需加锁,避免多次读数据。 应用场景:多个读 少量写 写相较于读具有更高优先级 rcu保持数据指针的引用…

完整教程:机器学习入门,用Lima在macOS免费搭建Docker环境,彻底解决镜像与收费难题!

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

go语言中的基本数据类型

go语言中的基本数据类型package mainimport ("fmt" )func main() {// 整型var a int = 10var b int8 = -8var c uint16 = 65535var d int64 = 1234567890// 浮点型var e float32 = 3.14var f float64 = 2.71…

实用指南:rsync +生产级 lsyncd 实时同步方案

实用指南:rsync +生产级 lsyncd 实时同步方案2025-09-21 16:51 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: …

锁定Nvidia驱动版本

在 Ubuntu 系统中,NVIDIA 显卡驱动通常通过系统的包管理器(如 apt)进行管理和更新。要防止 NVIDIA 驱动程序自动更新,你可以锁定当前安装的驱动版本,这样即使系统进行了更新,驱动程序也会保持在当前版本。以下是…

第二十一章-sql 注入-union 联合注入 (1)

用户须知1.免责声明:本教程作者及相关参与人员对于任何直接或间接使用本教程内容而导致的任何形式的损失或损害,包括但不限于数据丢失、系统损坏、个人隐私泄露或经济损失等,不承担任何责任。所有使用本教程内容的个…

Android开发参考

WorkManager https://www.cnblogs.com/octsun/category/2471458.html

求出e的值

//题意:利用公式e = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! 求e ; //输入:只有一行,该行包含一个整数n(2<=n<=15),表示计算e时累加到1/n!。 //输出:输出只有一行,该行包含计算出来的e的值,要求打印小数…

CSP-S模拟24

前言: 没写完的话就先咕着,先滚去学文化课了。 \(T1:\) 炒币 \(T2:\) 凑数 \(T3:\) 同构 \(T4:\) 重建