专业的编程技术博客社区

网站首页 > 博客文章 正文

【C++】使用C++20的模块(c++20模块化)

baijin 2024-08-13 00:55:30 博客文章 4 ℃ 0 评论

引言


从C++11开始,C++经历了11、14、17、20、23等多个版本更新。C++23标准虽然已经发布了,但编译器实现还处在实验中。其他几个版本中,C++11和C++20是两个大版本,它们包含的特性能够显著改变程序员的生活。C++11已经广泛使用了,但C++20还在普及当中,距离普遍使用估计还有一段时间。


今天想分享一下C++20中的模块,主要是感觉这个特性实在算得上一次语言革命。其他的特性当中,许多是“由专家设计并为专家设计”,但模块特性足以影响到每一个程序员的日常。


模块示例


过去组织程序的方式主要是通过头文件(.h)声明接口,源文件(.cpp)实现接口,有了模块以后,声明和实现可以写在一个模块接口单元文件(.ixx)当中。以下是一个简单的示例,文件名称是basefunction.ixx。


整个文件分为三部分:

第一部分使用export和module关键字导出一个模块,语法是export module NAME,NAME就是要导出的模块名称;


第二部分使用export导出接口,其实就和普通的接口声明一样,只不过在声明前加一个export关键字,表明这个接口要给客户使用。这里分别导出了一个函数和一个类。导出一个类,意味着其所有公共接口被导出。


第三部分实现了接口定义,和普通的函数/类定义没有区别。因为模块只会被编译一次,所以将定义和声明放在一起,不会导致多重定义。


下面调用一下模块BaseFunction中的函数,测试如下:


首先使用import关键字导入模块,接着使用模块中的接口,最后得到结果。


使用模块


要使用模块特性,需要针对编译器做一些设置。IDE使用visual studio 2022,新建一个C++工程项目firstApp,然后依次点击项目-firstApp属性,界面如下:



在语言界面将C++标准设置为最新,并将最后两个模块选项设置为是,然后应用。


接下来就可以创建模块单元了,在新建文件页面,文件类型选择模块接口单元,创建完成后就可以编写前面的代码了。


模块特点


相比于传统的.h/.cpp方式,模块的特点主要有以下几个:

  1. 编译时间短:对于.h文件,如果被100个翻译单元包含,该文件就要被处理100次,对于模块只会被处理一次。
  2. 不依赖顺序,如果h2中包含了h1, 那么h2中的宏定义可能会影响到h1中的代码定义。对于模块来说没有这个问题。
  3. 没有传染性,如果h2包含了h1,当其他文件引用h2的时候被迫引用了h1。对于模块来说,m2中导入了m1,当用户导入m2的时候并不会一并导入m1,这意味着模块没有传染性。



我觉得其中最重要的一点可能就是编译时间了,书上的说法是:


在代码量大了10倍的前提下,编译速度还快了10倍!!这是什么概念呢?意味着原来需要编译一个小时的工程,现在可能几分钟就好了。仅此一点,我多么盼望C++20能够早日进入工作中!


总结


C++20在2020年底发布,引入了一些重大革新,包含模块、概念、协程、范围、视图、管道等,其中前三个是语言层面的变化,后三个是标准库中的变化,还有一些其他的更新。总之,C++20足以改变程序员对于编程的思考方式。


今天主要分享了模块的基本用法,主要涉及export/import关键字,export用来导出一个模块和接口,import用来导入一个模块。一般情况下,模块中的声明和定义写在一个ixx文件中,如果想把声明和定义分开,也可以实现,下面是一个示例:




模块最显著的优点是可以大幅缩短程序的编译时间,这对于实际工程非常有益处。另外考虑到旧代码的迁移成本,C++20标准允许模块和头文件混合使用


从语法上看,模块应该是借鉴了Python,不知道未来C++会不会发展成C++Py。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表