当前位置: 首页 > backend >正文

【C++】Module CPP:模块化编程 Demo

一、C++20 模块简介

C++20 模块是 C++ 语言发展史上的重要革新,它从根本上改变了代码组织方式。相比传统的头文件(#include)机制,模块具有以下核心优势:

  1. 隔离编译:模块独立编译,避免重复编译头文件
  2. 符号控制:通过 export 精确控制导出内容
  3. 消除污染:不会引入无关的宏定义和符号
  4. 加快编译:生成预编译模块接口(BMI)提升编译速度
  5. 强封装性:实现真正的逻辑单元封装

二、项目结构解析

cpp20-module-demo/
├── CMakeLists.txt           # 项目主配置
├── main.cpp                 # 入口文件
├── math/                    # 数学模块
│   ├── CMakeLists.txt       # 模块级配置
│   ├── math.cppm            # 模块接口声明
│   └── math_impl.cpp        # 模块具体实现
└── io/                      # IO模块(结构同上)

文件扩展名说明:.cppm 是模块接口单元的惯用扩展名,但并非强制要求

三、模块接口单元详解

1. 数学模块接口(math.cppm)

module;                            // 全局模块段开始
#include <iostream>                // 必须在此包含标准库头文件export module math;                // 声明并导出模块export int add(int a, int b);      // 导出函数声明
export int multiply(int a, int b); // 另一个导出函数

关键要素解析:

  • module; 开启全局模块段,用于包含传统头文件
  • export module 声明模块并导出接口
  • export 关键字控制导出的符号

2. IO模块接口(io.cppm)

module;
#include <iostream>  // 标准库必须前置包含export module io;export void print_result(const char* label, int value);

重要规则:

  • 所有标准库头文件必须在全局模块段包含
  • 接口文件中只能包含不会产生冲突的头文件
  • 导出的函数必须显式声明返回类型

四、模块实现单元详解

1. 数学模块实现(math_impl.cpp)

module math;  // 指定所属模块int add(int a, int b) {return a + b;
}int multiply(int a, int b) {return a * b;
}

2. IO模块实现(io_impl.cpp)

module;                  // 开启全局模块段
#include <iostream>      // 实现中使用标准库也需要前置包含module io;               // 指定所属模块void print_result(const char* label, int value) {std::cout << label << value << std::endl;
}

实现单元要点:

  • 不需要 export 关键字
  • 若实现中用到标准库,仍需在全局模块段包含
  • 实现文件与接口文件通过 module 模块名 建立关联

五、主程序模块导入

import math;  // 导入数学模块
import io;    // 导入IO模块int main() {int sum = add(3, 4);       // 使用模块导出函数int product = multiply(3, 4);print_result("Sum:    ", sum);print_result("Product:", product);return 0;
}

导入机制特点:

  • import 取代传统 #include
  • 只能访问模块导出的符号
  • 导入顺序无关紧要

六、CMake 配置解析

1. 顶层配置(CMakeLists.txt)

cmake_minimum_required(VERSION 3.28)
project(cpp20_module_demo LANGUAGES CXX)set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF)# 强制使用支持模块的生成器
if (NOT CMAKE_GENERATOR MATCHES "Ninja" AND NOT MSVC)message(FATAL_ERROR "请使用 Ninja 或 MSVC 构建系统")
endif()add_subdirectory(math)
add_subdirectory(io)add_executable(cpp20-module-demo main.cpp)
target_link_libraries(cpp20-module-demo PRIVATE math_mod io_mod)

关键配置:

  • 要求 CMake 3.28+ 以获得完整模块支持
  • 必须使用 Ninja 或 MSVC 生成器
  • 通过 target_link_libraries 隐式传递模块依赖

2. 模块级配置(math/CMakeLists.txt)

add_library(math_mod)target_sources(math_modPUBLICFILE_SET cxx_modules TYPE CXX_MODULES FILES math.cppmPRIVATEmath_impl.cpp
)set_target_properties(math_mod PROPERTIESCXX_STANDARD 20CXX_EXTENSIONS OFF
)

模块构建要点:

  • FILE_SET cxx_modules 声明模块接口文件
  • 接口文件放在 PUBLIC 作用域
  • 实现文件放在 PRIVATE 作用域
  • 必须显式设置 C++20 标准

3. 模块级配置(io/CMakeLists.txt)

add_library(io_mod)target_sources(io_modPUBLICFILE_SET cxx_modules TYPE CXX_MODULES FILES io.cppmPRIVATEio_impl.cpp
)set_target_properties(io_mod PROPERTIESCXX_STANDARD 20CXX_EXTENSIONS OFF
)

七、构建与运行指南

  1. 生成构建系统(使用 Ninja):
mkdir build
cd build
cmake -G Ninja ..
  1. 编译项目:
cmake --build .
  1. 运行程序:
./cpp20-module-demo

预期输出:

Sum:    7
Product:12

八、重要注意事项

  1. 头文件包含规则

    • 所有 #include 必须位于全局模块段
    • 模块单元中禁止包含可能产生冲突的头文件
  2. 模块实现单元

    • 必须严格对应接口单元命名
    • 同一模块可以有多个实现单元
    • 实现单元之间不可见彼此的非导出符号
  3. 构建系统限制

    • 目前只有 MSVC 和 Clang 提供完整支持
    • GCC 的模块实现仍在开发中
    • CMake 需要 3.28+ 版本
  4. 符号可见性

    • 未导出的符号具有模块内部链接性
    • 不同模块的同名符号不会冲突
http://www.xdnf.cn/news/6475.html

相关文章:

  • 【C#】Thread.Join()、异步等待和直接join
  • C++delete详解剖析
  • 工具类来生成蓝牙指令
  • Java 序列化(Serialization)
  • 奇妙协同效应,EtherNet IP与PROFINET网关优化半导体生产线
  • Git .gitattributes 文件用途详解
  • Baklib知识中台驱动智能服务新实践
  • ZCC6303x-60V/1.2MHz 高效率升压 LED 恒流驱动替代SY7301
  • 【图片识别工具】批量单据识别批量重命名,批量OCR识别图片文字并重命名,批量改名工具的使用步骤和注意事项
  • Modbus TCP转Profinet网关:数字化工厂异构网络融合的核心枢纽
  • pciutils-3.5.5-win64工具的使用方法
  • Java大师成长计划之第23天:Spring生态与微服务架构之服务发现与注册中心
  • 使用命令行拉取 Git 仓库
  • 数学复习笔记 9
  • 自学嵌入式 day 18 - 数据结构 1
  • 嵌软面试每日一阅----FreeRTOS
  • SpringBoot实现简单的API代理服务器
  • Sumsub 活体检测与人证对比 Java Demo
  • pytorch训练可视化工具---TensorBoard
  • Linux 防火墙 firewalld 实战配置教程!
  • 将.pt文件执行图像比对
  • Java详解RabbitMQ工作模式之发布订阅模式
  • 具备AI功能的银河麒麟桌面操作系统已正式上市
  • 手搓传染病模型(SEI - SEIAR )
  • xp_cmdshell bcp 导出文件
  • 道通龙鱼系列-混合翼无人机:垂直起降+长时续航
  • 嵌入式自学第二十二天(5.15)
  • 02、基础入门-Spring生态圈
  • 云上玩转 Qwen3 系列之三:PAI-LangStudio x Hologres构建ChatBI数据分析Agent应用
  • 机器学习第十三讲:独热编码 → 把“红黄蓝“颜色变成001/010/100的数字格式