C++20新特性_模块(Modules)

文章目录

  • [第一章 C++20核心语法特性](#第一章 C++20核心语法特性)
    • [1.4 模块 (Modules)](#1.4 模块 (Modules))
      • [1.4.1 隔离原理](#1.4.1 隔离原理)
      • [1.4.2 示例](#1.4.2 示例)
      • [1.4.3 模块与头文件比较](#1.4.3 模块与头文件比较)

本文记录C++20新特性之模块 (Modules)。

第一章 C++20核心语法特性

1.4 模块 (Modules)

在C++20之前,C++和C包含头文件时,都使用#include包含,这是一种文本替换机制,主要可以概括三大痛点。

1 编译速度极慢:#include 仅仅是简单的文本复制。如果一个头文件被 100 个源文件包含,编译器就必须解析这个头文件 100 次。对于庞大的标准库(如 或 ),这带来了巨大的重复工作量。

2 宏隔离性差:头文件中定义的宏(Macros)会"泄漏"到包含它的源文件中,甚至影响后续包含的其他头文件,导致难以排查的命名冲突和 Bug。

3 依赖地狱:头文件的包含顺序可能会影响代码行为,且很难清晰地看到一个文件到底依赖了哪些具体符号.

C++20引入了模就是为了提供一种语义化、编译一次、隔离性强的代码共享机制,这是C++诞生40年来首次对代码头文件组织方式的一次变革。

1.4.1 隔离原理

模块引入了两个关键字 export 和 import

独立编译:模块单元(Module Unit)被编译成一种二进制格式(BMI, Binary Module Interface)。当其他文件 import 这个模块时,编译器直接读取这个预编译好的二进制接口,而不是重新解析源代码。这使得编译速度呈数量级提升。

真正的隔离:模块内部定义的宏、未导出的函数和类型,对外部是完全不可见的。import 一个模块不会像 #include 那样把一堆垃圾符号倒进你的全局命名空间。

初始化顺序:模块提供了更明确的初始化顺序保证,减少了"静态初始化顺序大灾难"发生的概率。

1.4.2 示例

下面示例中,定义一个模块math_utils.ixx,并在主模块中完成调用。

cpp 复制代码
export module math;	// 声明 这是一个 math 模块

// 2 导出 export 需要给外部使用的部分
export int add(int a, int b)
{
	return a + b;
}

// 没有 export 的函数,外部无法访问
int helper(int a) 
{
	return a * 2;
}

// 导出使用了非导出函数的函数
export int double_add(int a, int b) 
{
	return helper(add(a, b));
}

在主模块中导入 自定义模块:

cpp 复制代码
import math;        // 导入自定义的模块

    void test()
    {
        std::cout << "add() " << add(1, 2) << std::endl;
        // 3 
		std::cout << "double_add() " << double_add(5, 3) << std::endl;
        // 16 
    }

示例2:模块分区

对于大型项目,一个模块可能非常大,我们可以将模块分为多个分区,在一个主模块中汇总分模块。下面将math模块分为 sub和add分模块,然后在math主模块导出分模块内容。

math_add.ixx (分区文件)

cpp 复制代码
export module math:add; // 声明属于 math 模块的 add 分区

export int add(int a, int b) { return a + b; }

math_sub.ixx (分区文件)

cpp 复制代码
export module math:sub; // 声明属于 math 模块的 sub 分区

export int sub(int a, int b) { return a - b; }

math.ixx (主模块接口)

cpp 复制代码
export module math; // 定义主模块

export import :add; // 导出并重新发布 add 分区
export import :sub; // 导出并重新发布 sub 分区

1.4.3 模块与头文件比较

下面是模块和头文件的比较。

相关推荐
啟明起鸣1 天前
【C++20新特性】概念约束特性与 “模板线程池”,概念约束是为了 “把握未知对象”
开发语言·c++·c++20·模板线程池
linweidong2 天前
虎牙C++面试题及参考答案(上)
stl·vector·线程·内存管理·c++20·c++面试·c++调用
吐泡泡_3 天前
C++20(概念和约束)
c++20
訫悦6 天前
体验在Qt中简单使用C++20的协程
qt·c++20·协程
fpcc10 天前
C++20中的预处理器宏——__VA_OPT__
c++20
Codeking__12 天前
C++20的consteval和constinit(接C++11的constexpr)
算法·c++20
六bring个六15 天前
C++20协程
c++20·协程
C++实习生15 天前
Visual C++ 2005 Express 中文版
express·c++20
Ethan Wilson17 天前
VS2019 C++20 模块相关 C1001: 内部编译器错误
开发语言·c++·c++20
DYS_房东的猫17 天前
《 C++ 零基础入门教程》第10章:C++20 核心特性 —— 编写更现代、更优雅的 C++
java·c++·c++20