news 2026/8/21 7:25:40

每日一个C++知识点|虚函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
每日一个C++知识点|虚函数

C++虚函数

作为C++程序员,“多态”绝对是绕不开的核心知识点,而撑起多态的关键技术,正是今天要聊的虚函数

一、先搞懂:虚函数到底是啥?

一句话概括:基类中加了virtual关键字的成员函数,就是虚函数

它的核心“魔法”的是:当用基类指针指向子类对象时,调用这个函数会自动执行子类的版本,而不是基类的!

举个生活中的例子:

  • 基类就像“动物”,有个“叫”的行为;
  • 子类是“狗”“猫”,继承了“动物”,但“叫”的方式不一样(狗汪汪、猫喵喵);
  • 没有虚函数时:用“动物指针”指向“狗”,调用“叫”会输出“动物叫”(认指针类型);
  • 有了虚函数后:同样的指针指向“狗”,会输出“汪汪叫”(认对象真实身份)。

这就是虚函数的核心价值——让指针“认清”对象的真实面目,实现多态!

二、3步实现虚函数多态

光说不练假把式,咱们用代码一步步实现上面的“动物叫”例子,一看就懂~

第一步:定义基类,给函数加virtual

先创建“动物”基类,把“叫”函数设为虚函数(加virtual关键字):

#include<iostream>usingnamespacestd;// 基类:动物classAnimal{public:// 虚函数:动物叫virtualvoidmakeSound(){cout<<"动物发出叫声~"<<endl;}};

第二步:定义子类,重写虚函数

创建“狗”和“猫”两个子类,继承Animal,并重写makeSound函数。这里可以加override关键字(可选,但强烈推荐),明确表示“我在重写基类的虚函数”,避免写错参数/返回值:

// 子类:狗(继承动物)classDog:publicAnimal{public:// 重写虚函数,加override更规范voidmakeSound()override{cout<<"汪汪汪!小狗在叫~"<<endl;}};// 子类:猫(继承动物)classCat:publicAnimal{public:voidmakeSound()override{cout<<"喵喵喵!小猫在叫~"<<endl;}};

第三步:测试多态效果

用基类指针指向不同的子类对象,调用makeSound,看看会不会自动匹配对应版本:

intmain(){// 基类指针Animal*animalPtr;// 指向狗对象Dog dog;animalPtr=&dog;animalPtr->makeSound();// 输出:汪汪汪!小狗在叫~// 指向猫对象Cat cat;animalPtr=&cat;animalPtr->makeSound();// 输出:喵喵喵!小猫在叫~return0;}

运行结果完全符合预期!同一个基类指针,指向不同子类对象时,自动调用子类的函数——这就是虚函数实现的多态,是不是很简单?

三、必记避坑点:3个关键规则

学会用法还不够,这3个坑一定要避开,否则容易出bug或内存泄漏!

1. 析构函数必须设为虚函数

如果基类指针指向子类对象,删除指针时如果析构函数不是虚函数,会只调用基类的析构函数,子类的资源释放不掉,导致内存泄漏

正确做法:基类析构函数加virtual:

classAnimal{public:virtualvoidmakeSound(){...}// 虚析构函数virtual~Animal(){cout<<"动物基类析构"<<endl;}};classDog:publicAnimal{public:voidmakeSound()override{...}~Dog()override{cout<<"小狗子类析构"<<endl;}};// 测试:删除基类指针指向的子类对象Animal*ptr=newDog();deleteptr;// 会先调用Dog析构,再调用Animal析构,无内存泄漏

2. 这两个函数不能是虚函数

  • 构造函数:对象还没创建完成,虚函数表还没初始化,无法实现虚函数效果;
  • 静态函数:静态函数属于类,不属于对象,而虚函数依赖对象的真实类型,冲突。

3. 用override明确重写,避免笔误

重写时如果参数类型、个数、返回值写错(比如把void makeSound()写成void makeSound(int)),编译器不会报错,而是当成新函数——加了override后,编译器会检查是否真的重写了基类虚函数,有错直接提示!

四、一句话总结

虚函数的核心就是:用virtual关键字标记基类函数,让子类能重写,最终实现“基类指针指向子类对象时,调用子类函数”的多态效果

掌握虚函数,你就打通了C++多态的“任督二脉”,后续学习继承、接口设计等知识点都会更轻松~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/20 15:34:41

3大突破性创新!Qwen3-235B-A22B重新定义大语言模型智能边界

3大突破性创新&#xff01;Qwen3-235B-A22B重新定义大语言模型智能边界 【免费下载链接】Qwen3-235B-A22B-MLX-8bit 项目地址: https://ai.gitcode.com/hf_mirrors/Qwen/Qwen3-235B-A22B-MLX-8bit 在人工智能技术飞速发展的今天&#xff0c;阿里通义实验室推出的Qwen3-…

作者头像 李华
网站建设 2026/8/21 0:36:30

torchtune分布式评估揭秘:多节点同步计算困惑度的技术突破与实战指南

当大语言模型参数量突破千亿级别&#xff0c;传统单节点评估已无法满足需求。torchtune如何实现1024节点分布式评估的零误差困惑度计算&#xff1f;多节点同步、性能优化、数据并行等关键词背后&#xff0c;隐藏着怎样的技术革命&#xff1f;本文将带你深入探索分布式评估的完整…

作者头像 李华
网站建设 2026/8/20 20:40:47

多引擎自由切换:Codex智能模型管理终极指南

还在为单一AI模型无法满足多样化开发需求而困扰&#xff1f;Codex的多引擎智能切换功能让你在5分钟内掌握不同AI模型的无缝切换技巧&#xff0c;大幅提升开发效率。本指南将带你深入了解如何配置、管理和优化多个AI引擎&#xff0c;打造专属的智能开发工作流。 【免费下载链接】…

作者头像 李华
网站建设 2026/8/21 5:53:41

AffectNet表情识别数据集终极使用指南

AffectNet表情识别数据集终极使用指南 【免费下载链接】AffectNet数据集资源下载说明 AffectNet数据集是一个专为表情识别研究设计的大规模资源&#xff0c;包含丰富的表情标签&#xff0c;为开发者和研究者提供了宝贵的实验材料。通过简单的网盘下载&#xff0c;您可以快速获取…

作者头像 李华
网站建设 2026/8/21 4:23:13

多智能体协同架构:构建分布式AI交互系统的5个关键技术

多智能体协同架构&#xff1a;构建分布式AI交互系统的5个关键技术 【免费下载链接】CopilotKit Build in-app AI chatbots &#x1f916;, and AI-powered Textareas ✨, into react web apps. 项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit 在现代应用…

作者头像 李华
网站建设 2026/8/20 22:33:49

K8S-Statefulset控制器

一、Statefulset控制器&#xff1a;概念、原理解读StatefulSet是为了管理有状态服务的问题而设计的。有状态服务StatefulSet是有状态的集合&#xff0c;管理有状态的服务&#xff0c;它所管理的Pod的名称不能随意变化。数据持久化的目录也是不一样&#xff0c;每一个Pod都有自己…

作者头像 李华