现代 C++20 实战高手课
卢誉声
Autodesk 首席工程师
3781 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 29 讲
现代 C++20 实战高手课
15
15
1.0x
00:00/00:00
登录|注册

02|Modules(中):解决编译性能和符号隔离的银弹

你好,我是卢誉声。
上一讲我们聊到开发者为了业务逻辑划分和代码复用,需要模块化代码。但随着现代 C++ 编程语言的演进,现代 C++ 项目的规模越来越大,即便是最佳实践方法,在不牺牲编译性能的情况下,也没有完全解决符号可见性符号名称隔离的问题。
如果从技术的本质来探究“模块”这个概念,其实模块主要解决的就是符号的可见性问题。而控制符号可见性的灵活程度和粒度,决定了一门编程语言能否很好地支持现代化、标准化和模块化的程序开发。一般,模块技术需要实现以下几个必要特性。
每个模块使用模块名称进行标识。
模块可以不断划分为更多的子模块,便于大规模代码组织。
模块内部符号仅对模块内部可见,对模块外部不可见。
模块可以定义外部接口,外部接口中的符号对模块外部可见。
模块可以相互引用,并调用被引用模块的外部接口(也就是符号)。
我们在上一讲中仔细讲解了 include 头文件机制,虽然它在一定程度上解决了同一组件内相同符号定义冲突的符号可见性问题,但头文件代码这种技术方式实现非常“低级”,仍无法避免两个编译单元的重复符号的符号名称隔离问题。我们迫切需要一种更加现代的、为未来编程场景提供完备支持的解决方案。
而今天的主角——C++ Modules,在满足上述特性的基础上,针对 C++ 的特性将提供一种解决符号隔离问题的全新思路。我们一起进入今天的学习,看看如何使用 C++ Modules 解决旧世界的问题?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

C++ Modules是一项旨在解决C++编译性能和符号隔离问题的新技术。该技术旨在取代传统的头文件使用,实现模块化编程。通过模块声明和导出声明,C++ Modules实现了模块内外符号的可见性控制。文章介绍了C++ Modules的基本概念和用法,包括模块声明、导出声明、模块接口单元和模块实现单元的划分,以及模块片段的使用。通过掌握C++ Modules的关键细节,开发者可以更方便地声明模块、引用模块、使用模块提供的接口,并编写更易于维护的代码。C++ Modules为C++语言提供了一种全新的思路,解决了旧世界的符号隔离问题,为大规模代码组织和现代化、标准化的程序开发提供了支持。文章还介绍了模块分区和模块所有权的概念,以及如何在实际项目中使用C++ Modules来组织代码。总的来说,C++ Modules为C++开发者提供了更高效、更灵活的模块化编程方式,极大地提升了代码组织和维护的便利性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 C++20 实战高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • Ak
    怎么感觉C++越来越像Java和python😅

    作者回复: C++的演进过程必定要不断借鉴其他的语言模型中的优点,这样才能不断现代化,在保持更高的性能的同时提升生产力。但是,C++跟Java和Python还是存在一个根本性区别,就是C++在演进过程中始终秉持着这样一个思想,即能在编译时解决的计算问题,就一定不要推迟到运行时。所以可以看到,自C++11之后推出的几乎所有新特性,都是为编译时服务的。这也是C++与其他编程语言之间最大的区别之一。

    2023-01-18归属地:广西
    5
  • 阿阳
    前端开发中,JavaScript的模块化方案发展多年了,历史中也出现了各种模块化方案,浏览器现在支持es module方案。感觉js的模块化探索走在前列。现在不太理解编译型语言的模块化和js这种解释型语言的模块化,有什么异同?

    作者回复: 在ES Module之前,JS的模块化方案主要是各类“事实标准”,整体混乱且问题多多,ES Module的定案也花费了相当之多的时间,浏览器能够支持ES Module也是近些年的事情了,出于兼容性考量大部分前端项目还会沿用类似于webpack的方案。 而C++由于更多的历史遗留问题、技术限制甚至是标准委员会内不同大公司之间的一些博弈,导致Modules标准到C++20才得以定案。 模块化的目的就是名称(符号)隔离,并且支持控制模块内名称(符号)的可见性,从这个目的上无论是解释性语言和编译性语言其实是一致的,不同点在于实现原理、实现限制与因语言本身设计思路以及历史遗留问题导致的设计与实现的差异,这些都体现在具体的设计细节与实现技术细节上,就算不同编译性语言之间(比如Java与Rust)与不同解释性语言之间(比如Python与ES)也会有很大差异,但是本质的设计目的一致,所以基本设计构思是不会有差别的。

    2023-02-11归属地:江苏
    1
  • Geek1185
    C++发展的过程中一直要兼容前面的用法,感觉越来越复杂了

    作者回复: C++本身因为需要向下兼容C语言就导致了很高的复杂性,但这也是C++的设计哲学,保证C++具备极佳的性能。但是一旦用了新的特性就可以部分抛弃对应的旧特性,这样就可以在工程上简化C++的复杂性,这也是C++演进的目标。我们作为开发者,要适当尝试去逐渐迭代使用新的特性,丢弃一些过去的惯用法,保证自己的编程习惯控制在一个大致固定的范围内,这也是为什么说C++20会是一个比较关键的时间节点,让大家逐步从C++11甚至更早的编程习惯下,过渡到新的编程世界中。

    2023-01-19归属地:山东
    1
  • 常振华
    我觉得不好用,花里胡哨的。C++最大的问题是库太少了,不像python和java那样想写个啥到处都是现成的库。用Modules的话,就只需要.cpp不需要.h了?

    作者回复: 1.其实并不是花里胡哨,而是C++在语法兼容性上存在很重的历史负担,而且不能增添不必要的运行时成本,导致很多现代语言特性在C++中的实现就会变得非常“复杂”、“脆弱“,需要更多的技巧来集成到项目中。至于C++的库,其实在互联网时代之前C/C++的库绝对是最丰富的——想想看GNU的那么多库,而且Linux的传统是,但凡有一个应用,大概率会提供对应的.h声明和二进制动态库,基本都是给C/C++用的,所以其实C/C++并不缺少成熟的第三方库,只不过不如Python/Java那么方便。但到了互联网时代之后,Java/Python由于其使用率以及库/模块的集成便利程度,自然在成熟库的数量和丰富性上与C++不在一个等级。另外由于C++缺少标准的第三方模块仓库,所以一般找第三方库都要去GitHub自己挖掘,并且集成难度必然相对于Java/Python更高,这也是C++早期羸弱的Module机制导致的(再加上各个平台不一致的ABI标准),最终形成了一个比较恶劣的第三方库生态环境。 2.用Modules本质就是只需要.cpp或者说模块文件,而不再区分.h/.cpp。但其实Modules一般也是需要划分声明文件和实现文件,和.h/.cpp的分工有异曲同工之妙。

    2023-08-29归属地:广东
  • 亘古谣
    我下载了源代码看了, 发现.ixx 和 .cpp里面的内容一样的。 我的理解.ixx不是向外提供的接口文件么, 怎么和实现文件一样?

    作者回复: 目前cmake生成的Visual Studio工程在使用C++ Modules时无法正常将源代码标记为模块接口或者模块实现,但如果源代码后缀名是ixx时就会将对应的文件作为模块接口/模块实现编译,因此我们将cpp文件复制了一个相同的ixx文件,以自动适配Visual Studio项目。

    2023-03-23归属地:四川
  • Geek_7c0961
    mac os 上的 clang 对c++20支持十分有限,不知道在环境配置上面有啥好的建议么?

    作者回复: 不知道你的clang版本号是多少,如果版本比较旧可以自己下载新版本源代码编译。但是clang对C++20的支持在3个主流编译器中的确是比较糟糕的,如果条件允许可以安装一个Windows虚拟机,然后使用VS,综合来说,就目前,Visual Studio对C++20的支持是最完善的。

    2023-01-31归属地:美国
  • 小龚小龚 马到成功 🔥
    不会考虑用户的心智负担吗?

    作者回复: 悉心采纳。可以考虑每个标题作为一个章节来学习。后续会针对内容编排进行调整。

    2023-01-23归属地:江苏
  • xuyong
    有点复杂了啊

    作者回复: 看起来概念复杂,但是在工程应用中其实非常简单(比如可以看后面的示例项目章节),而且不需要有很深入的理解就可以受益于现在的modules体系。可以期待一下 Modules(下),参考具体的代码实战有助于快速理解和掌握本课的内容。

    2023-01-21归属地:北京
  • 西钾钾
    helloworld.cpp 是需要需改为 helloworld.cppm 吗?

    作者回复: 从gcc和clang的新规定是可以将模块文件后缀名命名成.cppm,但其实这个是无所谓的,后缀名依然可以继续使用传统的.cpp。

    2023-01-19归属地:浙江
  • 西钾钾
    建议搞一个代码仓库

    作者回复: 即将跟随课程提供给大家。

    2023-01-18归属地:浙江
    2
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部