0

0

c++中如何定义虚函数实现多态_c++多态性基本实现原理【核心】

冰火之心

冰火之心

发布时间:2026-03-12 12:41:03

|

740人浏览过

|

来源于php中文网

原创

虚函数必须在基类中用virtual显式声明,否则不构成多态;派生类重写需用override确保正确性;含虚函数的类析构函数必须为virtual,否则delete基类指针时派生类析构逻辑不执行。

c++中如何定义虚函数实现多态_c++多态性基本实现原理【核心】

虚函数必须用 virtual 显式声明,否则不构成多态

在基类中不加 virtual 的函数,哪怕派生类里写了同名同参函数,调用时也只看指针/引用的静态类型,不会动态绑定。这是最常踩的坑:以为“函数名一样+继承了”就自动多态,结果发现 Base* p = new Derived(); p->func(); 调的还是 Base::func()

实操建议:

立即学习C++免费学习笔记(深入)”;

人民网AIGC-X
人民网AIGC-X

国内科研机构联合推出的AI生成内容检测工具

下载
  • virtual 必须写在基类函数声明处(头文件里),不能只在定义(.cpp)里加
  • 派生类重写时可加 override(C++11 起),编译器会检查是否真有对应虚函数,避免拼错名或参数不匹配
  • 纯虚函数写成 virtual void func() = 0;,含纯虚函数的类无法实例化,强制派生类实现

析构函数不加 virtual 会导致资源泄漏

如果基类析构函数不是虚函数,用 Base* p = new Derived(); delete p; 时,只会调 Base::~Base()Derived 的析构逻辑(比如释放内存、关文件句柄)完全不会执行——这不是“没调对”,是根本不会进派生类析构函数。

实操建议:

立即学习C++免费学习笔记(深入)”;

  • 只要类设计为被继承(尤其有子类要 new/delete),基类析构函数必须声明为 virtual
  • 即使基类析构函数函数体为空,也要写 virtual ~Base() = default;virtual ~Base() {}
  • 用智能指针(如 std::unique_ptr<base>)也不能绕过这点:delete 操作仍依赖虚析构

虚函数表(vtable)是编译器自动生成的指针数组,不是 C++ 标准但所有主流实现都用

每个含虚函数的类,编译器会在其对象内存布局开头塞一个隐藏指针(vptr),指向该类唯一的虚函数表。调用虚函数时,实际是通过 vptr 查表跳转——所以虚函数调用比普通函数多一次内存读取,但现代 CPU 分支预测很成熟,开销几乎可忽略。

关键影响:

  • 虚函数会让类失去 POD 类型属性,影响 memcpy、memset、union 使用等底层操作
  • 对象大小会增加(通常是 8 字节,64 位系统下 vptr 大小)
  • 模板特化或 constexpr 函数里不能出现虚函数调用,因为绑定发生在运行时

多态生效的前提是“通过指针或引用调用”,直接用对象调用不触发虚机制

Derived d; d.func(); —— 这永远调 Derived::func(),哪怕 func() 是虚函数;而 Base& b = d; b.func(); 才走虚调用流程。很多人把多态理解成“函数能被重写”,忽略了调用方式这个硬性前提。

常见错误现象:

  • 传值返回派生类对象,接收到基类对象后调用虚函数,结果是基类实现(因为发生了切片,vptr 已被替换成基类的)
  • 函数参数写成 void foo(Base b)(传值),应改为 void foo(const Base& b)void foo(Base* b)
  • std::vector 存派生类对象,会切片,必须用 std::vector<:unique_ptr>></:unique_ptr>

虚函数机制本身不复杂,真正容易出问题的地方,往往藏在对象生命周期管理、传参方式和内存布局这些看似“外围”的环节里。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

562

2023.09.20

c语言union的用法
c语言union的用法

c语言union的用法是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型,union的使用可以帮助我们节省内存空间,并且可以方便地在不同的数据类型之间进行转换。使用union时需要注意对应的成员是有效的,并且只能同时访问一个成员。本专题为大家提供union相关的文章、下载、课程内容,供大家免费下载体验。

129

2023.09.27

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

186

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

134

2025.11.27

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

55

2025.09.03

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

287

2023.11.13

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.2万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号