详解C++中“virtual”的概念及其含义

在C++的面向对象编程中,“virtual”是一个至关重要的关键字,它主要用于实现多态性(polymorphism),通过它,可以实现基类指针指向派生类对象时的动态绑定。本文将深入探讨C++中“virtual”的底层原理、使用方法以及应用场景。

一、virtual的底层原理

“virtual”关键字的底层原理涉及到C++中的虚函数表(vtable)和虚函数指针(vptr)。

  1. 虚函数表(vtable):每个包含虚函数的类都有一个虚函数表,其中存储了该类的虚函数的地址。虚函数表是在编译阶段静态生成的,每个类有且只有一个虚函数表。
  2. 虚函数指针(vptr):每个对象(实例)都有一个虚函数指针,指向该对象的虚函数表。这个指针是在对象创建时动态分配的,通过它可以实现在运行时的动态绑定。

当我们使用“virtual”关键字声明一个成员函数时,编译器会在虚函数表中为这个函数生成一个条目,并在每个对象中添加一个指向虚函数表的指针(即vptr)。这样,在运行时,通过这个指针就可以实现正确地调用派生类的虚函数。

二、virtual的使用方法

在C++中,使用“virtual”关键字声明虚函数的方法如下:

 

cpp

class Base {
public:
virtual void virtualFunction() {
// Base class implementation
}
// Other members...
};
class Derived : public Base {
public:
void virtualFunction() override {
// Derived class implementation
}
// Other members...
};

在基类中使用“virtual”关键字声明虚函数。派生类可以选择性地使用“override”关键字来显式重写基类中的虚函数,这有助于提高代码的可读性和维护性。

三、virtual的应用场景

“virtual”关键字广泛应用于面向对象程序设计中的多态性实现,主要用途包括但不限于:

  1. 运行时多态性:允许基类指针或引用指向派生类对象,并在运行时根据对象的实际类型调用正确的函数。
  2. 接口类:通过纯虚函数(纯虚函数没有实现,如virtual void func() = 0;),实现接口类,只定义接口而不实现具体功能,由派生类实现。
  3. 实现虚析构函数:确保在删除派生类对象时调用正确的析构函数,防止内存泄漏。
四、注意事项
  1. 虚函数的使用将导致类对象占用更大的内存空间:这是因为编译器给每一个包括虚函数的对象添加了一个隐藏成员——指向虚函数表的指针。无论一个类对象中定义了多少个虚函数,虚函数指针只有一个。相应地,每个对象在内存中的大小要比没有虚函数时大4个字节(32位主机,不包括虚析构函数)。
  2. 基类中的析构函数必须为虚函数:否则会出现对象释放错误。如果不将基类的析构函数声明为“virtual”,那么在调用delete语句时将调用基类的析构函数,而不是应当调用的派生类的析构函数,从而出现对象释放错误的问题。
  3. 重写与重载的区别:重写是派生类对基类同名函数的“本地改造”,要求函数特征标完全相同(包括参数的数目、类型和顺序)以及返回值都必须与基类中的函数一致;而重载则是同一个类中,内部的同名函数具有不同的参数列表。
五、总结

“virtual”关键字通过虚函数表和虚函数指针的机制,实现了C++中的运行时多态性,使得程序在处理复杂继承体系和动态对象分配时更为灵活和高效。通过本文的介绍,希望读者能够更好地理解和应用“virtual”关键字,正确地在C++中使用多态性特性,提高代码的灵活性和可维护性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

若依前后端分离版集成ShardingSphere-补充版代码演示

拉取项目&#xff1a;https://gitee.com/y_project/RuoYi-Vue。前后端分离版本新建数据库&#xff0c;字符集选择utf8mb4。导入mysql文件。 主pom文件中引入依赖 <!-- 分库分表引擎 --><dependency><groupId>org.apache.shardingsphere</groupId><…

Postman接口测试:全局变量/接口关联/加密/解密

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 全局变量和环境变量 全局变量&#xff1a;在postman全局生效的变量&#xff0c;全局唯一 环境变量&#xff1a;在特定环境下生效的变量&#xff0c;本环境内唯一 …

基于PHP的民宿预订管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的民宿预订管理系统 一 介绍 此民宿预订管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。(附带配套设计文档) 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册…

Elasticsearch:使用 Open Crawler 和 semantic text 进行语义搜索

作者&#xff1a;来自 Elastic Jeff Vestal 了解如何使用开放爬虫与 semantic text 字段结合来轻松抓取网站并使其可进行语义搜索。 Elastic Open Crawler 演练 我们在这里要做什么&#xff1f; Elastic Open Crawler 是 Elastic 托管爬虫的后继者。 Semantic text 是 Elasti…

NVM:安装配置使用(详细教程)

文章目录 一、简介二、安装 nvm三、配置 nvm 镜像四、配置环境变量五、使用教程5.1 常用命令5.2 具体案例 六、结语 一、简介 在实际的开发和学习中可能会遇到不同项目的 node 版本不同&#xff0c;而出现的兼容性问题。 而 nvm 就可以很好的解决这个问题&#xff0c;它可以在…

【HarmonyOS】HarmonyOS 和 Flutter混合开发 (一)之鸿蒙Flutter环境安装

【HarmonyOS】HarmonyOS 和 Flutter混合开发 &#xff08;一&#xff09;之鸿蒙Flutter环境安装 一、前言 flutter作为开源适配框架方案&#xff0c;已经在Android&#xff0c;IOS&#xff0c;Web&#xff0c;Window四大平台进行了适配&#xff0c;一套代码&#xff0c;可以同…

期权懂|期权新手入门知识:个股期权标的资产的作用

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 期权新手入门知识&#xff1a;个股期权标的资产的作用 个股期权标的资产的作用主要体现在以下几个方面‌&#xff1a; &#xff08;1&#xff09;基本面影响‌&#xff1a; 标的资…

Unity超优质动态天气插件(含一年四季各种天气变化,可用于单机局域网VR)

效果展示&#xff1a;https://www.bilibili.com/video/BV1CkkcYHENf/?spm_id_from333.1387.homepage.video_card.click 在你的项目中设置enviro真的很容易&#xff01;导入包裹并按照以下步骤操作开始的步骤&#xff01; 1. 拖拽“EnviroSky”预制件&#xff08;“environme…

【算法】【优选算法】链表

目录 一、链表常用技巧与操作总结二、2.两数相加三、24.两两交换链表中的节点3.1 迭代3.2 递归 四、143.重排链表五、23.合并K个升序链表5.1 堆5.2 分治5.3 暴力枚举 六、25.K个⼀组翻转链表 一、链表常用技巧与操作总结 技巧&#xff1a; 画图解题。使用虚拟头结点。像有插入…

【面试】Redis 常见面试题

一、介绍一下什么是 Redis&#xff0c;有什么特点? Redis 是一个高性能的 key-value 内存数据库。 不同于传统的 MySQL 这样的关系型数据库&#xff0c;Redis 主要使用内存存储数据&#xff08;当然也支持持久化存储到硬盘上&#xff09;&#xff0c;并非是使用 “表” 这样…

【Linux】NET9运行时移植到低版本GLIBC的Linux纯内核板卡上

背景介绍 自制了一块Linux板卡(基于全志T113i) 厂家给的SDK和根文件系统能够提供的GLIBC的版本比较低 V2.25/GCC 7.3.1 这个版本是无法运行dotnet以及dotnet生成的AOT应用的 我用另一块同Cortex-A7的板子运行dotnet的报错 版本不够&#xff0c;运行不了 而我的板子是根本就识…

MySQL Explain 分析SQL语句性能

一、EXPLAIN简介 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。 &#xff08;1&#xff09; 通过EXPLAIN&#xff0c;我们可以分析出以下结果&#xff1a; 表的读取顺序数据读取…

vue3实现商城系统详情页(前端实现)

目录 写在前面 预览 实现 图片部分 详情部分 代码 源码地址 总结 写在前面 笔者不是上一个月毕业了么&#xff1f;找工作没找到&#xff0c;准备在家躺平两个月。正好整理一下当时的毕业设计&#xff0c;是一个商城系统。还是写篇文章记录下吧 预览 商品图片切换显示…

uniapp 微信小程序 功能入口

单行单独展示 效果图 html <view class"shopchoose flex jsb ac" click"routerTo(要跳转的页面)"><view class"flex ac"><image src"/static/dyd.png" mode"aspectFit" class"shopchooseimg"&g…

6.1 初探MapReduce

MapReduce是一种分布式计算框架&#xff0c;用于处理大规模数据集。其核心思想是“分而治之”&#xff0c;通过Map阶段将任务分解为多个简单任务并行处理&#xff0c;然后在Reduce阶段汇总结果。MapReduce编程模型包括Map和Reduce两个阶段&#xff0c;数据来源和结果存储通常在…

聚观早报 | 百度回应进军短剧;iPad Air将升级OLED

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 12月18日消息 百度回应进军短剧 iPad Air将升级OLED 三星Galax S25 Ultra配色细节 一加Ace 5系列存储规格 小米…

CH582F BLE5.3 蓝牙核心板开发板 60MHz RAM:32KB ROM:448KB

CH582F BLE5.3 蓝牙核心板开发板 60MHz RAM:32KB ROM:448KB 是一款基于南京沁恒&#xff08;WCH&#xff09;推出的高性能、低功耗无线通信芯片CH582F的开发板。以下是该开发板的功能和参数详细介绍&#xff1a; 主要特性 双模蓝牙支持&#xff1a; 支持蓝牙5.0标准&#xff0…

【软件工程复习】

第1章 软件工程概述 1.2软件工程 ​ 1983年IEEE给出的定义&#xff1a;“软件工程是 开发、运行、维护和修复软件的系统方法 ” 1.4软件生存期 软件开发和运行维护由三个时期组成&#xff1a; 软件定义时期软件开发时期运行维护时期 里程碑指可以用来标识项目进程状态的事…

DuckDB: 从MySql导出数据至Parquet文件

在这篇文章中&#xff0c;介绍使用DuckDB将数据从MySQL数据库无缝传输到Parquet文件的过程。该方法比传统的基于pandas方法更高效、方便&#xff0c;我们可以从DuckDB cli实现&#xff0c;也可以结合Python编程方式实现&#xff0c;两者执行核心SQL及过程都一样。 Parquet格式…

safe area helper插件

概述 显示不同机型的必能显示的区域 实现步骤 引入safearea&#xff0c;引入其中的safearea的csharp 为cancas加入gameobject gameobject中加入safearea脚本 将UI作为这个gameobject的子物体&#xff0c;就可以完成显示