0

0

C++怎么写接口 C++抽象类和纯虚函数实现【精讲】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-03-09 14:39:18

|

584人浏览过

|

来源于php中文网

原创

c++接口必须声明至少一个纯虚函数(virtual void f() = 0),且不可提供实现;析构函数须为virtual;子类实现须用override,终点类可加final;仅靠头文件+inline无法替代虚函数机制。

c++怎么写接口 c++抽象类和纯虚函数实现【精讲】

怎么用 class 声明一个真正不可实例化的接口

不能靠注释或命名约定,C++ 接口必须由编译器强制约束。关键不是“叫 Interface”,而是至少有一个 virtual 函数被声明为 = 0,且类中没有定义该函数的实现。

常见错误是只写 virtual void func();(没加 = 0),结果类仍可实例化;或者写了 = 0 却在类内提供了函数体(语法错误)。

  • 纯虚函数必须写成:virtual void draw() = 0;,不能带函数体
  • 构造函数可以有,但必须是 protected(否则派生类无法调用)
  • 析构函数也应声明为 virtual,否则通过基类指针 delete 派生对象会未定义行为

overridefinal 在接口继承中为什么不能省

不加 override,编译器不会检查你是否真的重写了基类的纯虚函数——拼错函数名、参数类型差一个 const 或引用符,都会导致子类仍含未实现的纯虚函数,从而无法实例化,且错误提示往往指向子类构造,而非函数签名不匹配。

final 不是装饰,它阻止进一步派生,适用于你明确不希望用户再继承该实现类的场景(比如标准库中的 std::string_view 类型策略)。

立即学习C++免费学习笔记(深入)”;

Stable Diffusion 2.1 Demo
Stable Diffusion 2.1 Demo

最新体验版 Stable Diffusion 2.1

下载
  • 子类实现时务必加 override:例如 void draw() override { ... }
  • 若确定该实现类是终点,加 final:例如 class Circle : public Shape final { ... };
  • 漏掉 override 可能导致静默失败:子类看似实现了接口,实则只是新增了一个同名函数

为什么不能只靠头文件 + inline 实现来“模拟”接口

有人试图在头文件里写一个只有声明的 class,再另起一个 inline 函数集合“假装”是接口。这绕不开 C++ 的 ODR(One Definition Rule)和链接模型:接口的本质是运行时多态,依赖 vtable 和虚函数调用机制,不是函数集合的静态绑定。

这种写法无法支持 std::unique_ptr<shape></shape> 持有不同子类对象,也无法用 dynamic_cast 安全下转型,更无法参与模板约束(如 requires std::derived_from<t shape></t>)。

  • 虚函数调用开销虽小,但它是多态的唯一标准路径;用函数指针或 std::function 模拟,失去类型安全和编译期检查
  • 头文件里只声明抽象类,实现放在 .cpp 中——这是常规做法,不是限制,而是避免模板膨胀和隐式内联带来的二进制兼容风险
  • 接口类本身不应含数据成员(或仅含 static constexpr),否则破坏“纯粹行为契约”的语义

抽象类作为模板参数时,std::is_abstract_vstd::is_polymorphic_v 怎么选

二者用途完全不同:std::is_abstract_v<t></t> 判断 T 是否为抽象类(即含未实现的纯虚函数),而 std::is_polymorphic_v<t></t> 判断 T 是否至少有一个 virtual 函数(包括虚析构函数)——后者是运行时类型识别(RTTI)的前提。

如果你在写泛型容器,想约束只能传入多态类型(以便用 dynamic_cast),该用 std::is_polymorphic_v;如果做编译期断言防止用户误传具体类当接口用,则用 std::is_abstract_v

  • 接口类一定满足 std::is_polymorphic_v,但反之不成立(比如只有虚析构的类不是抽象类)
  • 使用 static_assert 时注意:抽象类无法作为模板实参直接实例化,所以断言要放在 SFINAE 或 requires 子句之后
  • Clang 和 GCC 对 std::is_abstract_v 的处理一致,但 MSVC 在早期版本对空基类优化可能影响结果,建议测试实际编译器版本
接口真正的复杂点不在语法,而在设计边界:什么时候该把一个函数设为纯虚,什么时候留默认实现;子类是否必须重写某个行为;析构函数要不要公开。这些决定直接影响下游能否安全继承、能否正确销毁、能否被模板元编程识别——写完 = 0 只是开始,不是结束。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

561

2023.09.20

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

186

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

132

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1877

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

656

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2382

2025.12.29

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

59

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11万人学习

C 教程
C 教程

共75课时 | 5.3万人学习

C++教程
C++教程

共115课时 | 21.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号