网站首页 > 博客文章 正文
为什么要引入模块
在C++ 20之前,所有的代码组织都依赖于预处理器和头文件。这种方式主要存在以下四个问题:一是大型项目中,相同的头文件会被多次包含,导致编译时间延长;二是头文件之间复杂的相互引用关系难以管理,容易造成编译时错误;三是全局命名空间污染,不同的库可能定义相同的名字,导致冲突;四是修改一个头文件往往需要重新编译所有依赖它的源文件。
模块的引入,正是为了克服上述问题,从而提供一种更现代、更高效的代码组织方式。
模块的基本概念
在C++ 20中,模块是一种新的编译单元,称为模块单元(Module Unit)。模块允许我们将相关的代码组织在一个单独的文件中,这个文件可以是源文件(.cpp)或模块接口单元(.ixx或.cppm)。模块接口单元声明了模块中可供外部使用的实体(比如:类、函数、变量等),并且可以选择性地定义这些实体。
模块分为两个部分:模块接口和模块实现。
模块接口文件通常以.cppm(或.ixx)为扩展名,它定义了模块对外提供的接口。接口文件可以不包含任何实现代码,只负责声明,也可以提供具体的实现。
模块实现文件则是.cpp文件,包含了模块的具体实现细节,它通过导入对应的模块接口文件来访问接口声明。
定义模块
假如我们要创建一个名为math的模块,它提供了一些基础的数学函数。首先,我们创建模块接口文件math.cppm,示例代码如下。
export module math;
export double square(double x);
export double cube(double x);
在上面的示例代码中,export module math声明了模块的名字为math。export关键字则用来指示哪些函数或类型是模块的公共接口,可以被外部访问。
接下来,如果有具体的实现逻辑,我们可以在math_impl.cpp中实现。
module math;
// 实现细节可以放在这里
double square(double x)
{
return x * x;
}
double cube(double x)
{
return x * x * x;
}
另外,大型模块可以被分割成多个分区,每个分区有自己的接口和实现。比如:math模块可以分为algebra和geometry两个分区。
// math/algebra.cppm
export module math.algebra;
export double multiply(double a, double b);
// math/geometry.cppm
export module math.geometry;
export struct Point { double x, y; };
导入模块
在另一个源文件中,我们可以像下面的示例代码这样导入并使用math模块。
import math;
int main()
{
double result = square(5.0);
result = cube(3.0);
return 0;
}
注意:模块的编译与传统方式有所不同。模块接口文件首先被编译成模块接口单元(.ifc或特定格式的二进制文件),这个过程类似于将源代码编译成对象文件。然后,模块实现文件和使用这些模块的源文件被编译时,会直接链接这些预先编译好的接口单元,而不是再次处理头文件,大幅减少了编译时间。
总结
C++ 20的模块特性为C++编程带来了许多优势,包括:提高编译效率、减少头文件冗余、避免标识符冲突等。随着编译器对模块特性的支持不断完善和普及,模块将会成为C++编程中不可或缺的一部分。
如果想阅读最新的文章,或者有技术问题需要交流和沟通,可搜索并关注微信公众号“希望睿智”。
猜你喜欢
- 2025-08-03 C++语法进阶-字符:字符变量(char)
- 2025-08-03 c++26新功能—Read-Copy-Update
- 2025-08-03 为什么Linux之父那么讨厌C++ 他骂的这几点。句句扎心
- 2025-08-03 为什么Linux之父那么讨厌C++ 他骂的这几点!句句扎心
- 2025-08-03 20道qiao牛逼的c++/c面试题
- 2025-08-03 C++学习教程_C++语言随到随学_不耽误上班_0基础
- 2025-08-03 20天轻松入门《C++第四章——函数》——4经坛教育
- 2025-08-03 看完侯捷老师所有C++视频之后的总结
- 2025-08-03 C++11+ 泛型编程(模板)
- 2025-08-03 C++20并发库新成员jthread(续)
你 发表评论:
欢迎- 08-06nginx 反向代理
- 08-06跨表插入连续的日期,sheetsname函数#excel技巧
- 08-06初中生也能学的编程,不走弯路,先用后学
- 08-06find命令的“七种武器”:远不止-name和-type
- 08-06恶意代码常见的编程方式
- 08-06kali2021ping 外网不通
- 08-06因为一个函数strtok踩坑,我被老工程师无情嘲笑了
- 08-06hadoop集群搭建详细方法
- 18℃nginx 反向代理
- 最近发表
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- googlecloud (64)
- powershellfor (73)
- messagesource (71)
- plsql64位 (73)
- vueproxytable (64)
- npminstallsave (63)
- #NAME? (61)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- nacos启动失败 (64)
- ssh-add (70)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- qcombobox样式表 (68)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)