当前位置: 首页 > news >正文

虚函数(virtual)

虚函数(virtual)是基类指针/引用调用函数时,程序在运行时自动识别对象真实类型,执行子类重写的函数,而不是固定调用基类函数。

1.没有虚函数:静态绑定(早绑定)

编译器根据指针/引用的类型决定调用哪一个函数,编译阶段就确定好了。

class Bae{ public: void func(){ cout<<"基类函数"<<endl; } }; class Son:public Base{ public: void func(){ cout<<"子类函数"<<endl; } }; int main(){ Base*p=new Son() p->func();//没有virtual,永远调用 Base::func() }

明明指向了子类对象,却执行了基类方法,无法实现不同子类不同行为。

2.加了virtual,动态绑定(晚绑定)

class Base{ public: virtual void func() { cout<<"基类函数"<<endl; } }; class Son:public Base{ public: void func() override { cout<<"子类函数"<<endl; } }; int main() { Base* p=new Son(); p->func();//运行时识别真实类型,调用 Son::func() }

override是 C++11 引入的说明符,专门用于子类重写虚函数。

3.虚函数两大常见形态

3.1 普通虚函数

virtual void func();

基类提供默认实现,子类可选重写。

3.2 纯虚函数

virtual void SyncLog()=0;

  • 基类没有函数实现
  • 拥有纯虚函数的类=抽象类,不能直接实例化对象
  • 子类必须重写该函数,否则子类依然是抽象类,无法创建对象

👉 作用:定义一套统一接口,强制所有子类遵守规范。

4.基类的析构函数加virtual的场景

不是所有基类都要加virtual析构!只有一种场景强制要求:使用基类指针/引用指向子类对象,并且会通过基类指针执行delete

我们把场景分成两大类区分:

4.1 ✅必须写virtual ~Base()的场景

条件同时满足:

1.存在继承class Son:public Base

2.业务代码会:Base* p=new Son(); delete p;

典型例子

  • 你当前的策略模式抽象基类LogStrategy
  • 所有面向多态设计、作为接口的抽象类(含有纯虚函数)

这类类设计初衷就是让别人继承,并用基类指针管理子类对象,规范强制加上虚析构

class LogStrategy { public: virtual ~LogStrategy() = default; // 必要! virtual void SyncLog(const std::string &msg) = 0; };

4.2 ❌ 不需要、甚至不应该加 virtual 的场景

场景 1:不会通过基类指针 delete 子类

虽然有继承,但是永远不会执行delete 基类指针。 例如:对象全部定义在栈上、智能指针使用子类类型、不执行销毁动作。

Base obj; Son son; Base& ref = son; // 仅引用,不delete,不需要虚析构

场景 2:这个类禁止被继承(C++11final

class Test final {}; // final类不能被继承,完全不需要virtual析构

场景 3:只是普通工具类,设计初衷就不允许别人继承

很多底层工具类,没有设计成多态基类,继承只是偶然行为。

C++ 编码规范(如 Google 规范):如果一个类不打算作为多态基类,不要随便加 virtual。 代价:产生虚表、增加对象内存开销。

场景 4:组合优先于继承,根本不设计继承关系

很多类不对外提供继承接口,自然无需考虑。

5.一条黄金判断口诀(写代码直接套用)

如果你不确定未来会不会有人通过基类指针 delete 子类 → 保守加上虚析构;如果你明确这个类不是用来做多态接口、禁止继承 → 不要加 virtual。

6.一个高频误区澄清

误区:含有虚函数的类,析构就必须 virtual?

错误! 含有普通virtual函数 ≠ 一定会用基类指针delete子类。 只是绝大多数含有虚函数的类,都是为了实现多态,极大概率会执行delete 基类指针,所以工程上约定俗成:含有虚函数的基类,一律写上 virtual 析构

http://www.jsqmd.com/news/1288585/

相关文章:

  • 2026年07月:AED储存柜服务公司实力之选 - 优企名品
  • 进程溯源架构深度解析:witr如何实现跨平台进程因果关系追踪的终极方案
  • 斜率在股票中的应用
  • MARZOCCHI油泵代理商有哪些?从省级代理到行业集成商全图谱 - 品牌推荐大师
  • 适合女生稳定专业!凡谷学前 / 旅游专业,技能高考可读师范大专 - 湖北升学规划
  • 靠谱的网格川字塑料托盘厂家 - 米諾
  • 武汉凡谷电子职业技术学校 2026 技能高考 艺术高考招生专刊 - 湖北升学规划
  • 【MySQL】 InnoDB 锁等待排查与并发压测实验
  • 应用案例---100 米深井实时监测水位项目 - 水位监测系统观察员
  • 从单账号到矩阵帝国:AI自媒体矩阵搭建的黄金21天成长路径,含私有化训练数据集(仅开放72小时)
  • 如何在5分钟内为你的苹果触控板安装Windows专业驱动,获得原生级触控体验?
  • Path of Building PoE2终极指南:5步打造完美流放之路2角色
  • 基于matalab的FIR IP核滤波器系数生成
  • LMS算法C/C++实现:从原理到工业级自适应滤波代码
  • 2026Q2金华GEO优化AI推广服务商实力盘点|五金 / 汽配 / 机械设备 / 义乌工贸工厂专属|上门诊断落地、全域 AI 获客、地图同城引流靠谱服务商优选 - 企业品牌优选测评官
  • 成都单招复读培训机构哪些好——2027年四川单招复读培训 - 四川成都单招培训
  • 装修全流程避雷指南|安庆本地装修不踩坑,选安庆大维装饰一站式安心装新家 - 安庆大维装饰
  • 贵阳黄金回收引流套路拆解,识破虚假高价报价陷阱 - 日常比对手册
  • 放弃房屋继承权公证书怎么写?书写要点与线上申办步骤 - 指上通
  • AI 重构 RJ45 网口智能选型体系,根治通信丢包、EMI 超标、SMT 失效、供应链断供全链路技术痛点
  • AI 总把红色用错地方?你需要一张“颜色使用说明书“
  • 如何用pdfdir轻松管理PDF文档:智能书签生成完整指南
  • KMS_VL_ALL_AIO:3步实现Windows与Office永久激活的智能解决方案
  • 空号检测三网直连信令实时查询:99.99%准确率如何精准剔除停机、关机、空号三类无效号码
  • WinForm应用实战开发指南 - 如何开发工作流模块的审批会签操作(二)
  • Docker 部署 ERPNext:轻松搭建开源 ERP 企业管理平台
  • 工程化陷阱——离散化、延迟、饱和与奇点
  • 武汉凡谷电子职业技术学校招生简章及联系电话 - 湖北找学校
  • 乌鲁木齐塑木栈道,新疆防腐木专业生产厂家,大智景观木业工程案例汇总 - 米諾
  • Shell脚本编程进阶:从命令到健壮自动化程序的设计与实践