C++ const常數在多檔案程式設計中的3種用法

2020-07-16 10:05:21
《C++多檔案程式設計是什麼》一節提到,多檔案程式設計中程式碼的劃分原則是:將變數、函數或者類的宣告部分存放在 .h 檔案,對應的實現部分放在 .cpp 檔案中。值得一提得是,此規律適用於大部分場景,但本節要講的 const 常數是一個例外。

我們知道,用 const 修飾的變數必須在定義的同時進行初始化操作(除非用 extern 修飾,本節後續會講解)。與此同時,C++ 中 const 關鍵字的功能有 2 個,除了表明其修飾的變數為常數外,還將所修飾變數的可見範圍限制為當前檔案。這意味著,除非 const 常數的定義和 main 主函數位於同一個 .cpp 檔案,否則該 const 常數只能在其所在的 .cpp 檔案中使用。

那麼,如何定義 const 常數,才能在其他檔案中使用呢?接下來給讀者介紹 3 種在 C++ 多檔案程式設計中定義 const 常數的方法。

1) 將const常數定義在.h標頭檔案中

首先介紹一種最常用也最簡單的方法,就是將 const 常數定義在 .h 檔案中。

顯然此方式違背了“宣告位於 .h 檔案,定義(實現)位於 .cpp 檔案”的規律。在 C++ 多檔案程式設計中,還有 2 種特殊情況是違背此規律的,分別是類的定義和行內函式的定義,通常情況下它們也都定義在 .h 檔案中。

舉個例子(範例一):
//demo.h
#ifndef _DEMO_H
#define _DEMO_H
const int num = 10;
#endif

//main.cpp
#include <iostream>
#include"demo.h"
int main() {
    std::cout << num << std::endl;
    return 0;
}
專案執行結果為:

10

注意,將 const 常數定義在 .h 檔案中,為了避免標頭檔案被重複引入,推薦使用 #ifndef/#define/#endif 結構。除此之外,還有 2 中方式可以避免標頭檔案被重複引入,讀者可閱讀《C++防止標頭檔案被重複引入的3種方法》一文做詳細了解。

可以看到,使用此方式定義的 const 常數,只需引入其標頭檔案(比如這裡的 demo.h),就可以使用它。

2) 借助extern先宣告再定義const常數

當然,const 常數的定義也可以遵循“宣告在 .h 檔案,定義在 .cpp 檔案”,借助 extern 關鍵字即可。例如(範例二):
//demo.h
#ifndef _DEMO_H
#define _DEMO_H
extern const int num;  //宣告 const 常數
#endif

//demo.cpp
#include "demo.h"   //一定要引入該標頭檔案
const int num =10;  //定義 .h 檔案中宣告的 num 常數

//main.cpp
#include <iostream>
#include "demo.h"
int main() {
    std::cout << num << std::endl;
    return 0;
}
專案執行結果為:

10

前面講過,C++ const 關鍵字會限定變數的可見範圍為當前檔案,即無法在其它檔案中使用該常數。而 extern 關鍵字會 const 限定可見範圍的功能,它可以使 const 常數的可見範圍恢復至整個專案。

3) 借助extern直接定義const常數

值得一提的是,第 2 種使用 extern 定義 const 常數的方式,還可以做進一步優化。

以範例二為例,demo.cpp 和 main.cpp 中都引入了 demo.h,而 demo.h 檔案中只包含對 const num 常數的宣告。要知道 C++ 編譯器在執行專案時,會在預處理階段直接將 #include 引入的標頭檔案替換成該標頭檔案中的內容(就可以理解為傻瓜式的複製貼上)。

因此,我們可以將範例二中的專案做如下修改:
//demo.cpp
extern const int num =10;

//main.cpp
#include <iostream>
extern const int num;
int main() {
    std::cout << num << std::endl;
    return 0;
}
專案執行結果為:

10

顯然相比範例二,此專案中省略了 demo.h 標頭檔案的建立,一定程式上提高了專案的編譯效率。

本節介紹了 3 種在多檔案程式設計中使用 const 常數的方法,相比後 2 種藉助 extern 修飾 const 常數的方式,第一種方式更簡單、更常用,推薦讀者使用。