点击上方蓝字 江湖评谈设为关注/星标
前言
C++20添加了一个非常重要的特性Modules,这个特性相当于重新组织了C++代码文件的结构方式和编译方式。增加了可维护性,提高了编译性能,本篇看下。
C++20 Modules
新增的这个Modules特性主要用于取代传统的C++头文件(.h)和宏(macros)调用机制。
1.传统的头文件的方式
C++文件结构方式:
project/
|-----引用
|-----外部依赖
|-----头文件
| └── header.h
|------源文件
| └── header.cpp
| └── main.cpp
以加法运算和减法运算为例。
头文件:header.h
#pragma once
// 函数声明
int add(int a, int b);
int subtract(int a, int b);
源文件:header.cpp
#include "header.h"
// 函数实现
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
源文件:main.cpp
#include "header.h"
int main() {
int x = 10, y = 5;
std::cout << "Add: " << add(x, y) << std::endl;
std::cout << "Subtract: " << subtract(x, y) << std::endl;
getchar();
return 0;
}
2.C++20 Modules方式
C++文件结构方式:
project/
|-----引用
|-----外部依赖
|-----头文件
|------源文件
| └── AddModules.ixx
| └── AddModules.cpp
| └── main.cpp
把头文件直接取消,用ixx扩展名的模块来替代。
Modules定义文件:AddModules.ixx
export module AddModules; // 定义模块名称为 "AddModules"
export int add(int a, int b); // 导出函数
export int subtract(int a, int b);
AddModules.cpp:
module AddModules; // 声明实现属于模块 "math"
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
import AddModules; // 导入模块
#include <iostream>
int main() {
std::cout << "3 + 4 = " << add(3, 4) << '\n'; // 使用导出的函数
getchar();
return 0;
}
export
的内容会被视为私有,对模块外部不可见。而引入的时候只需要import <module_name>引入模块一次就可以了。- 冗余编译
:头文件被多次包含,导致重复的解析和编译。 - 宏污染
: #define
等宏容易导致命名冲突或意外行为。 - 缺乏封装
:头文件通常会暴露实现细节,难以限制可见性。
project/
├── main.cpp
├── math.ixx # 顶层模块接口文件
├── math_add.ixx # 子模块接口(分区)
└── math_subtract.ixx # 子模块接口(分区)
math_subtract.ixx:
module math:subtract; // 声明子模块,属于顶层模块 math
export int subtract(int a, int b) {
return a - b;
}
math_add.ixx:
module math:add; // 声明子模块,属于顶层模块 math
export int add(int a, int b) {
return a + b;
}
export module math; // 顶层模块声明
// 导入子模块
export import :add;
export import :subtract;
import math; // 导入顶层模块
#include <iostream>
int main() {
int x = 10, y = 5;
std::cout << "Add: " << add(x, y) << std::endl; // 使用子模块 math:add 的函数
std::cout << "Subtract: " << subtract(x, y) << std::endl; // 使用子模块 math:subtract 的函数
return 0;
}
结尾
C++20的Modules特性有效的解决了头文件带来的重复解析编译,意外冲突,暴露细节和导出函数不明等问题。算得上是对于C++的一次缺陷的修正。
往期精彩回顾
Rust会取代C++吗?
C++20 重量级的特性
C++20重量级特性:协程
关注公众号↑↑↑:江湖评谈