为什么应该用模块取代C/C++中的头文件? .

为什么应该使用模块(Module)替代头文件(Header)?

头文件糟透了!

众所周知,C程序在编译时一般会预处理头文件

为什么应该用模块取代C/C++中的头文件? ._第1张图片

 

常规解决办法如下:

[cpp] view plain copy print ?
  1. LLVM_WHY_PREFIX_UPPER_MACROS       
  2. LLVM_CLANG_INCLUDE_GUARD_H       
  3. template<class _Tp>    
  4. const _Tp& min(const _Tp &__a,                  
  5.                 const _Tp &__b);    
  6.                   
  7. #include <windows.h>    
  8. #undef min // because #define NOMINMAX    
  9. #undef max // doesn’t   


 

 

但结果依然不够理想,比较一下代码与程序大小你会发现:

为什么应该用模块取代C/C++中的头文件? ._第2张图片

 

另外,头文件形式的可扩展性天生不足。假设有n个源文件,每个源文件引用了m个头文件,那么构建过程的开销会是m×n。这在C++中表现得尤为糟糕。所以预说处理头文件是一个非常糟糕的解决方案。

C家族的模块系统

模块是什么?

  • 库的接口(API)
  • 库的实现

使用“import”导入已命名的模块:

为什么应该用模块取代C/C++中的头文件? ._第3张图片

 

import会在源文件中忽略预处理状态,并且选择性导入,所以弹性(resilience)非常好。

使用“import”会导入什么?

  • 函数、变量、类型、模板、宏,等等;
  • 公开API——其它的都隐藏;
  • 没有特别的命名空间机制。

C/C++引入模块会怎么样?

 

引入模块的目标在于:

  • 在源文件中指定模块名称;
  • API公开;
  • 没有头文件!

要编写一个模块非常简单,只需要使用export

为什么应该用模块取代C/C++中的头文件? ._第4张图片

 

但是这么做会遇到很多遗留问题:

  • 需要迁移现在基于头文件的类库;
  • 与不支持模块的编译器的互操作性
  • 工具需要理解模块;

所以应该使用引入模块的过渡方案——直接从头文件中构建模块这么做有以下好处:

  • 头文件有利于互操作;
  • 程序员不需要完全改变自己习惯的开发模式;

模块地图(Module Map)

模块地图是模块的关键,用来定位模块相关(子)模块,包含以下功能:

  • 模块定义命名(子)模块

为什么应该用模块取代C/C++中的头文件? ._第5张图片

 

  • 头文件在(子)模块中包含命名头文件的内容

    保护伞头文件(Umbrella Header)

     

  • 你可能感兴趣的:(C++,C++,Module,预编译,import,import,macros)