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

C++基础知识:虚函数和纯虚函数

完整总结虚函数和纯虚函数的用法、特点、适用场景和注意事项。


一、虚函数(virtual

特点

  1. 定义

    • 在基类中用 virtual 修饰的成员函数。

    • 子类可以选择重写(override),也可以不重写。

  2. 实现要求

    • 必须有函数体(实现),否则编译/链接会报错。

    • 即便实现是空的 {},也要给。

  3. 多态

    • 通过基类指针或引用调用虚函数时,会发生动态绑定,实际执行的是子类的版本。

    • 如果子类没重写,就用基类的实现。

适用场景

  • 基类提供一个默认实现,子类可选是否覆盖。

  • 比如:

    class Shape {
    public:virtual void draw() { std::cout << "Default draw" << std::endl; }
    };
    

二、纯虚函数(= 0

特点

  1. 定义

    • 在基类中声明成 = 0

    • 语法:virtual ReturnType func() = 0;

  2. 实现要求

    • 不需要基类实现(但也可以写实现,少见)。

    • 子类 必须实现,否则子类仍然是抽象类,不能实例化。

  3. 抽象类

    • 含有至少一个纯虚函数的类是抽象类,不能直接实例化。

适用场景

  • 只想定义一个接口/约束,不提供默认实现。

  • 要求所有子类都必须实现自己的版本。

  • 比如:

    class Shape {
    public:virtual void draw() = 0;  // 强制子类实现
    };
    

三、对比总结

特性普通虚函数纯虚函数
是否必须有实现✅ 必须❌ 不需要(可写也可不写)
子类是否必须实现❌ 可选✅ 必须
基类能否实例化✅ 可以❌ 不行(抽象类)
用途提供默认行为,子类可选覆盖定义接口规范,强制子类实现

四、注意事项

  1. 析构函数要声明为虚函数

    • 如果基类会被继承,几乎总是应该写:

      virtual ~Base() {}
      
    • 防止通过基类指针释放子类对象时,子类析构函数不被调用,导致内存泄漏。

  2. 性能开销

    • 虚函数通过 虚函数表(vtable) 实现,有很小的额外开销(一次间接寻址),通常可以忽略。

  3. 覆盖(override)要用关键字

    • C++11 以后推荐加 override,防止拼写错误或签名不一致:

      void draw() override;
      
  4. 抽象类不能实例化

    • 含有纯虚函数的类是抽象类,不能创建对象,只能通过指针/引用来使用多态。

  5. 接口类

    • 如果一个类全是纯虚函数(且无成员变量),相当于 Java/C# 的“接口”。


五、什么时候用?

  • 普通虚函数

    • 基类能给出一个合理的默认实现;

    • 子类可选择是否覆盖。

    • 例如:日志接口,默认 log() 输出到控制台,子类可重写输出到文件。

  • 纯虚函数

    • 基类无法给出合理实现;

    • 只想定义一个规范,强制所有子类实现。

    • 例如:图形接口 draw(),不同图形必须自己画。


✅ 一句话总结:

  • 虚函数 = “有默认实现,子类可以改”。

  • 纯虚函数 = “这是个接口,子类必须自己写”。

http://www.dtcms.com/a/356019.html

相关文章:

  • 基于MATLAB的FIR滤波器设计与信号分离实现
  • 线性回归的法方程:原理与解析
  • 复习笔记11
  • 【K8s】整体认识K8s之pod
  • 【Git】Git 常用指令
  • 使用华为 USG6000防火墙配置安全策略
  • 今日行情明日机会——20250828
  • 驾驭巨量数据:HTTP 协议与大文件传输的多种策略
  • 【Python开源环境】Anaconda/Miniconda
  • 印度尼西亚数据源 PHP 对接文档
  • 从零搭建安全帽检测(8)— 泛化性检验:构建独立测试集与模型性能公正评估
  • 动态加载和异步调用tasklet/workqueue day63 ay64
  • 卷积神经网络搭建及应用
  • 对象之间属性拷贝(Bean Mapping)的工具MapStruct 和 BeanUtils
  • 多据点协作下的数据库权限与版本管理实战
  • BeforeEach与AfterEach注解的使用
  • React学习教程,从入门到精通, ReactJS - 安装:初学者指南(3)
  • iPhone17新品曝光!未来已来主题发布会即将登场
  • CSS入门学习
  • Vim 相关使用
  • Dify 从入门到精通(第 61/100 篇):Dify 的监控与日志分析(进阶篇)
  • 笔记本电脑蓝牙搜索不到设备-已解决
  • LoRA加入嵌入层、及输出头解析(63)
  • 实测阿里图像编辑模型Qwen-Image-Edit:汉字也能无痕修改(附实测案例)
  • 【 MYSQL | 基础篇 函数与约束 】
  • 响应式编程之Flow框架
  • cmd 中设置像 linux 一样设置别名(alias)
  • Xshell自动化脚本大赛实战案例及深度分析
  • 谷歌RecLLM,大模型赋能对话推荐算法系统
  • TUN模式端口冲突 启动失败如何解决?