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

【C/C++】虚函数

📘 C++ 虚函数详解(Virtual Function)


📌 什么是虚函数?

虚函数(Virtual Function) 是 C++ 中实现运行时多态(Runtime Polymorphism) 的核心机制。

它允许派生类 重写(Override) 基类的函数实现,使得通过基类指针或引用调用函数时,能根据对象的实际类型动态绑定到对应的实现。


🔧 虚函数的作用

作用说明
实现多态性允许基类指针/引用指向派生类对象,并调用派生类的方法
接口设计基类定义接口(纯虚函数),派生类实现具体功能
解耦代码业务逻辑与具体实现分离,提高代码可维护性

🛠️ 使用方式

1. 声明虚函数

class Base {
public:virtual void show() { std::cout << "Base class" << std::endl; }
};

2. 派生类重写虚函数

class Derived : public Base {
public:void show() override {  // C++11 强制重写检查std::cout << "Derived class" << std::endl;}
};

3. 通过基类指针/引用调用

Base* ptr = new Derived();
ptr->show();  // 输出 "Derived class"

⚠️ 虚析构函数

当基类可能被继承时,必须将析构函数声明为虚函数,防止内存泄漏:

class Base {
public:virtual ~Base() {}  // 虚析构函数
};

🧠 虚函数表(vtable)与虚函数指针(vptr)

  • 虚函数表(vtable):每个含虚函数的类都有一个虚函数表,存储虚函数的地址。
  • 虚函数指针(vptr):每个对象隐式包含一个指向其类虚函数表的指针。

⚠️ 底层机制无需手动干预,但理解原理有助于优化设计


⚖️ 注意事项

限制项说明
不能是静态函数静态函数属于类而非对象,无法动态绑定
不能是友元函数友元函数不属于类成员
默认参数值需谨慎默认参数在编译时绑定,可能引发意外行为
性能开销间接寻址调用,比普通函数慢 5-10 倍

📦 示例代码

#include <iostream>
using namespace std;class Shape {
public:virtual void draw() { cout << "Shape" << endl; }virtual ~Shape() {}  // 虚析构函数
};class Circle : public Shape {
public:void draw() override { cout << "Circle" << endl; }
};class Rectangle : public Shape {
public:void draw() override { cout << "Rectangle" << endl; }
};int main() {Shape* shapes[] = { new Circle(), new Rectangle() };for (auto s : shapes) {s->draw();  // 多态调用delete s;}return 0;
}

输出结果:

Circle
Rectangle

❓ 常见问题

问题回答
虚函数可以是 inline 吗?✅ 可以声明为 inline,但编译器会忽略 inline 优化
虚函数可以有默认参数吗?✅ 可以,但建议保持参数一致以避免混淆
构造函数可以是虚函数吗?❌ 不可以,构造期间对象类型未完全确定
虚函数可以是模板函数吗?❌ 不支持虚模板函数,但可以有虚函数模板特化

🔒 纯虚函数与抽象类

纯虚函数 是没有实现的虚函数,用于定义接口:

class Interface {
public:virtual void method() = 0;  // 纯虚函数
};
  • 包含纯虚函数的类称为抽象类,不能直接实例化。
  • 派生类必须实现所有纯虚函数,否则自身也是抽象类。

📊 总结

核心要点说明
多态性通过虚函数实现运行时动态绑定
接口设计纯虚函数定义接口,派生类实现细节
性能考量虚函数调用有间接寻址开销
安全销毁基类析构函数必须为虚函数
设计原则对扩展开放,对修改关闭(OCP)

📝 设计建议

📌 设计建议:

  1. 仅对需要多态的函数使用 virtual
  2. 抽象类作为接口时,析构函数必须为虚函数。
  3. 使用 override 显式标记重写函数(C++11 起)。

术语对照

  • Virtual Function → 虚函数
  • Pure Virtual Function → 纯虚函数
  • Abstract Class → 抽象类
  • Runtime Polymorphism → 运行时多态

http://www.xdnf.cn/news/4466.html

相关文章:

  • 某大型交通规划设计院转型实践:数智化破局复杂工程项目管理,实现高效人力资源一体化管理
  • 华为设备链路聚合实验:网络工程实战指南
  • 【LeetCode】高频 SQL 50题 题解
  • C语言编程--递归程序--Hanoi塔
  • 企业智能化第一步:用「Deepseek+自动化」打造企业资源管理的智能中枢
  • MEGA3:分子进化遗传学分析和序列比对集成软件
  • 检测内存条好坏有工具,推荐几款内存检测工具
  • github+ Picgo+typora
  • OpenCV提取图像中的暗斑/亮斑
  • IvorySQL 再次走进北京大学研究生开源公选课
  • onenet连接微信小程序(mqtt协议)
  • 【国产化】在银河麒麟ARM环境下离线安装docker
  • Spring 如何解决循环依赖问题?
  • JavaScript性能优化:从青铜到王者的进阶之路
  • 从人体姿态到机械臂轨迹:基于深度学习的Kinova远程操控系统架构解析
  • Kubernetes(k8s)学习笔记(九)--搭建多租户系统
  • QMK键盘固件配置详解
  • 2025.05.07-华为机考第三题300分
  • DIFY教程第四弹:通过工作流来创建一个SQL语句的执行器
  • 【计算机基础】任意进制转换方法详解
  • 资产管理系统对比评测:从传统模式到 AI 驱动的变革
  • 引用的使用
  • [Es_1] 介绍 | 特点 | 图算法 | Trie | FST
  • 【C/C++】errno/strerror 和 GetLastError()/FormatMessage 的区别
  • 模拟设计中如何减小失配
  • 4.系统定时器基本定时器
  • 操作系统——第四章(文件的物理结构以及与逻辑结构的对比)
  • Redis相关命令详解与原理
  • 【Agent】使用 Python 结合 OpenAI 的 API 实现一个支持 Function Call 的程序,修改本机的 txt 文件
  • 如何检查 Watchtower 是否正常工作及更新未生效的排查方法【日常排错】