C++20重量级特性:模块(Modules)

文摘   2024-12-11 09:07   新加坡  

点击上方蓝字 江湖评谈设为关注/星标




前言

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 <iostream>#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;}
main.cpp:
import AddModules; // 导入模块#include <iostream>int main() {    std::cout << "3 + 4 = " << add(34) << '\n'; // 使用导出的函数    getchar();    return 0;}
ixx文件里面定义的导出函数以export标记,非常容易识别。没有标记为 export 的内容会被视为私有,对模块外部不可见。而引入的时候只需要import <module_name>引入模块一次就可以了。
而头文件可能带来以下问题,则完全被Modules避免了。
  • 冗余编译
    :头文件被多次包含,导致重复的解析和编译。
  • 宏污染
    #define 等宏容易导致命名冲突或意外行为。
  • 缺乏封装
    :头文件通常会暴露实现细节,难以限制可见性。


2.C++20 Modules子模块方式
Modules可以分为多个代码部分,然后通过引入一个顶层模块,就可以直接调用所有子模块的导出函数。比如以下:
C++结构:
project/├── main.cpp├── math.ixx          # 顶层模块接口文件├── math_add.ixx      # 子模块接口(分区)└── math_subtract.ixx # 子模块接口(分区)
math_subtract.ixx:
module math:subtract; // 声明子模块,属于顶层模块 mathexport int subtract(int a, int b) {    return a - b;}
math_add.ixx:
module math:add; // 声明子模块,属于顶层模块 mathexport int add(int a, int b) {    return a + b;}
math.ixx:
export module math; // 顶层模块声明// 导入子模块export import :add;export import :subtract;
main.cpp:
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重量级特性:协程



关注公众号↑↑↑:江湖评谈 

江湖评谈
记录,分享,自由。
 最新文章