news 2026/7/14 0:24:02

《你真的了解C++吗》No.022:纯虚函数与抽象类的真正用途——契约式编程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《你真的了解C++吗》No.022:纯虚函数与抽象类的真正用途——契约式编程

《你真的了解C++吗》No.022:纯虚函数与抽象类的真正用途——契约式编程

导言:强制性的“蓝图”

在多态体系中,有时基类代表的是一个极其抽象的概念(比如“形状”或“文件对象”)。在这一层级,我们无法给出一个有意义的默认实现。

纯虚函数(Pure Virtual Function)允许我们只声明接口的“长相”,而将实现的责任完全推给派生类。这种机制将 C++ 类从单纯的“代码容器”提升到了“架构契约”的高度。


一、 语法本质:那一个= 0意味着什么?

当你写下virtual void draw() = 0;时,你并不是在给函数赋值为零,而是向编译器发出了三条指令:

  1. 禁止实例化:这个类现在成为了抽象类(Abstract Class)。你永远不能写出Shape s;这样的代码,编译器会报错。
  2. 虚表占位:在虚表(vtbl)中,该函数的条目被标记为一个特殊值(通常是空指针或指向一个名为__pure_virtual_called的错误处理函数)。
  3. 强迫继承者:任何继承自此类的子类,除非它也想当抽象类,否则必须重写(Override)这个函数。

二、 抽象类的核心用途:解耦与接口设计

1. 定义接口(Interface)

在 C++03 中,虽然没有interface关键字,但我们通过“只包含纯虚函数的类”来模拟它。这让调用者(客户端)只依赖于抽象的协议,而不依赖于具体的实现。

2. 实现契约式编程

抽象类定义了“做什么”,而派生类定义了“怎么做”。这种分离使得系统具备了极强的扩展性。例如,你可以编写一个处理Storage对象的函数,无论是DiskStorage还是CloudStorage,只要它们遵循Storage的契约,代码就能完美运行。


三、 纯虚函数可以有“身体”吗?

这是一个经常被忽略的冷知识:在 C++ 中,你可以为纯虚函数提供定义。

classShape{public:virtualvoiddraw()=0;};// 纯虚函数的定义voidShape::draw(){std::cout<<"Performing common shape prep...";}

为什么要这么做?
虽然子类仍然必须重写draw(),但子类的实现可以显式地调用Shape::draw()来执行一些通用的初始化逻辑。这既保证了子类必须提供个性化实现,又提供了共享代码的机会。


四、 避坑指南:纯虚析构函数

正如我们在 No.013 聊过的,基类的析构函数必须是虚的。但如果你想把类变成抽象类,却又没有合适的成员函数可以纯虚化,该怎么办?

你可以把析构函数声明为纯虚的:

classBase{public:virtual~Base()=0;};// 必须提供定义!Base::~Base(){}

注意:你必须为纯虚析构函数提供函数体。因为子类析构时会自动向上调用基类析构函数,如果没有定义,程序在链接阶段会崩溃。


总结:架构师的指挥棒

  • 虚函数:提供默认方案,你可以改,也可以不改。
  • 纯虚函数:不提供默认方案(通常),你必须自己动手。
  • 抽象类:它是思想的化身,不是物理存在的实体。

下一篇预告:我们通常谈论public继承表示“是一个(Is-a)”的关系。但如果你使用private继承,这种血缘关系就会变得非常诡异。它不再是“是一个”,而是“用……实现”。

➡️《你真的了解C++吗》No.023:私有继承的哲学——“实现基于”而非“是一种”。

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

AI人体骨骼检测角度计算:关节弯曲度自动测量系统教程

AI人体骨骼检测角度计算&#xff1a;关节弯曲度自动测量系统教程 1. 引言&#xff1a;AI驱动的运动姿态分析新范式 随着人工智能在计算机视觉领域的深入发展&#xff0c;人体姿态估计&#xff08;Human Pose Estimation&#xff09;已成为智能健身、康复训练、动作捕捉等场景…

作者头像 李华
网站建设 2026/7/13 4:02:54

GLM-4.6V-Flash-WEB无法启动?实例控制台操作详解

GLM-4.6V-Flash-WEB无法启动&#xff1f;实例控制台操作详解 智谱最新开源&#xff0c;视觉大模型。 1. 背景与问题定位 1.1 GLM-4.6V-Flash-WEB 简介 GLM-4.6V-Flash-WEB 是智谱 AI 推出的最新开源多模态视觉大模型&#xff0c;支持网页端交互推理与API 接口调用双模式&…

作者头像 李华
网站建设 2026/7/13 6:46:53

HunyuanVideo-Foley社交媒体:TikTok/B站内容创作者利器

HunyuanVideo-Foley社交媒体&#xff1a;TikTok/B站内容创作者利器 随着短视频平台如TikTok和B站的迅猛发展&#xff0c;内容创作者对视频制作效率与质量的要求日益提升。音效作为增强沉浸感、强化情绪表达的重要元素&#xff0c;传统上依赖人工挑选或专业音频库&#xff0c;耗…

作者头像 李华
网站建设 2026/7/13 3:33:12

ComfyUI离线安装终极指南:5分钟掌握无网络环境部署技巧

ComfyUI离线安装终极指南&#xff1a;5分钟掌握无网络环境部署技巧 【免费下载链接】ComfyUI-Manager 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Manager 你是否曾在没有网络的环境中为ComfyUI节点安装而苦恼&#xff1f;当外网访问受限时&#xff0c;传统…

作者头像 李华
网站建设 2026/7/1 4:40:14

企业宣传照自动脱敏?AI打码批量处理实战案例

企业宣传照自动脱敏&#xff1f;AI打码批量处理实战案例 1. 引言&#xff1a;企业宣传中的隐私困境与AI破局 在企业对外宣传过程中&#xff0c;员工合影、办公场景、客户交流等照片是展示企业文化与服务的重要素材。然而&#xff0c;这些图像中往往包含大量人脸信息&#xff…

作者头像 李华
网站建设 2026/7/1 23:36:42

GLM-4.6V-Flash-WEB部署教程:Jupyter一键启动详细步骤

GLM-4.6V-Flash-WEB部署教程&#xff1a;Jupyter一键启动详细步骤 智谱最新开源&#xff0c;视觉大模型。 1. 引言 1.1 学习目标 本文旨在为AI开发者、研究人员及技术爱好者提供一份完整、可落地的GLM-4.6V-Flash-WEB部署指南。通过本教程&#xff0c;您将掌握&#xff1a; …

作者头像 李华