Home Item 27 - 模塊(modules)(中文)
Post
Cancel

Item 27 - 模塊(modules)(中文)

模塊(modules)

C++20 引入了模塊(modules),這是自 C++11 引入的範本(templates)以來最大的語言特性改變之一。 模塊旨在替代傳統的頭文件機制,以改善編譯時間並提供更好的封裝性。

傳統的 c++ include 真的好難用喔,像 python 都可直接 import 模組使用 ex: import numpy as np 我們來看一下 include 造成的問題吧

傳統 include 的問題

編譯時間過長

  1. 重複解析:每次編譯器處理一個源文件時,會重新解析並處理所有包含的頭文件。這些頭文件可能包含大量重複的代碼,導致編譯時間增加。

  2. 依賴關係複雜:頭文件的嵌套包含關係複雜,可能導致多個頭文件被多次包含,進一步增加編譯時間。

宏污染

命名衝突:頭文件中使用的宏定義可能會污染全局命名空間,導致意外的命名衝突和難以排查的錯誤。

不可控的依賴

依賴傳播:一個頭文件包含另一個頭文件,依賴關係會逐層傳播,導致編譯單元的依賴關係變得非常複雜和不可控。

封裝性差

內部實現洩露:頭文件通常會暴露實現細節,破壞封裝性。任何對頭文件的修改都會迫使所有依賴它的文件重新編譯。

模塊(modules)如何解決這些問題

減少編譯時間:

  1. 一次性解析:模塊只需解析和編譯一次,然後可以被多次導入,而無需重複解析。這顯著減少了編譯時間。
  2. 模塊化邊界:模塊引入了更明確的邊界,減少了不必要的依賴傳播。

消除宏污染:

命名空間隔離:模塊不直接使用宏,從而避免了命名衝突和全局命名空間污染的問題。

簡化依賴管理:

清晰的依賴關係:模塊導入的依賴關係更加明確,減少了依賴傳播,從而使依賴管理變得更加簡單和可控。

提高封裝性:

隱藏實現細節:模塊可以更好地封裝實現細節,只導出必要的接口。這樣,內部實現的改動不會迫使所有依賴的文件重新編譯。

Demo 在 VS2022 使用 Module

在 VS2022 使用 Module 很容易 首先,先在語言的地方選擇 c++20, 否則編譯會失敗 (Visual Studio 2019 版本 16.8 及以上,或者 Visual Studio 2022,這些版本支持 C++20 模塊)

Desktop View

新增項目

Desktop View

C++ 模組介面單位(.ixx)

Desktop View

filename:math.ixx 我們定義了 function , class, struct

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
export module math;

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

export class Math {
public:
    int add(int a, int b);
    int subtract(int a, int b);
};

export struct Point
{
    int x;
    int y;
};

filename:math_impl.cpp 開頭需指名要實作的模組 class 實作部分

1
2
3
4
5
6
7
8
9
module math;

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

int Math::subtract(int a, int b) {
    return a - b;
}

main function 開頭 import 模組 math

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import math;
#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
    int result = add(5, 3);
    std::cout << "Result: " << result << std::endl;

    Math math;
    std::cout << "math.add(5,3): " << math.add(5,3) << std::endl;
    std::cout << "math.subtract(5,3): " << math.subtract(5,3) << std::endl;

    Point p{ .x = 0, .y = 10 };
    std::cout << p.x << " " <<p.y<< std::endl;

    return 0;
}

檔案如同下面顯示

Desktop View

執行結果 Desktop View

很簡單吧! Happy coding!

☝ツ☝

This post is licensed under CC BY 4.0 by the author.

👈 ツ 👍

Item 27 - Modules(English)

Item 7 (1/2) - 智能指针(smart pointers)(中文)