外部連結 External Linkage

在上一章 內部連結 Internal Linkage 中我們介紹了內部連結的概念,這一章我們要來介紹他的兄弟觀念:外部連結。

一樣,我們會先介紹什麼是外部連結,接著講該如何使一個變數或函數擁有外部連結,最後講為什麼我們需要它。

什麼是外部連結

上一章我們了解到什麼是內部連結,簡單來說,如果一個變數或函數被設定為內部連結,那麼只有該檔案可以看得到它。

如果你有理解內部連結,那麼我想外部連結也可以很好的理解了!

外部連結的意義在於,如果一個變數或函數被設定為外部連結,那麼除了當前的檔案以外,其他的檔案也可以看得到它。

那你可能會問,我們什麼時候會需要一個變數或函數被其他檔案看到呢?

誒不用急,讓我們繼續讀下去。

全局變數

在上一章,我們了解到什麼是全局變數。

我們也知道在 main() 函數之外建立的變數會被預設擁有外部連結,除非使用 static 或是 const 這兩個關鍵字。

那麼,我們可不可以將變數從內部連結改為外部連結呢?

可以的!那就是用 extern 這個關鍵字!

比方說:

// 這個 extern 有和沒有意思一樣
extern int a{0};

// 利用 extern 將 b 更改為帶有外部連結
extern const int b{0};

int main()
{
    return 0;
}

那麼我們該如何在另一個檔案讀取來自另一個檔案的變數呢?這裡我們要來介紹前向聲明 Forward declaration。

Forward declaration 基本上就是在告訴當前文件說,誒有一個變數(或函數)存在於另一個檔案中喔!這樣在該文件使用那個變數時,才不會不知所措。

這就好像如果我們有提前看到一個陌生人的照片,那麼看到他本人的時候就不會覺得那麼陌生了!

我們來看一個例子:

test.cpp

extern const int a{3};

main.cpp

// forward declaration
// 告訴當前文件有一個全局變數 a 被定義在其他檔案中
extern const int a;

int main()
{
    std::cout << a << std::endl;
    return 0;
}

函數

在前一章我們學到,函數其實預設是擁有外部連結的!

但是如果想要在其他檔案使用存在於另一個檔案的函數,我們一樣需要做一個前向聲明 forward declaration 的動作。

我們直接來看一個例子:

test.cpp

int print()
{
    std::cout << "This is from test.cpp" << std::endl;
}

main.cpp

// 向前聲明 forward declaration
int print()

int main()
{
    print();
    return 0;
}

我們可以發現結果為:

This is from test.cpp

如果不做 forward declaration,那麼在 main() 中呼叫 print() 就會報錯,因為程式碼會試圖在 main.cpp 中找尋 print(),而想當然的他不會找到。

為什麼要外部連結

外部連結的核心意義在於「共享」。它主要提供了幾個好處:

當然,以下是關於外部連結使用案例和好處的三個要點:

  • 共享全局變數:外部連結允許全局變數在程序的不同文件中被訪問和修改,當然 const 除外。
  • 訪問共享函數:外部連結讓函數能夠被程序的不同文件使用,促進了程式碼的重複使用性。
  • 程式庫開發:外部連結對於創建程式庫來說非常重要,因為他促進了模塊化的設計,增強了程式庫的維護性和擴展性。

總結

這章我們了解了什麼是外部連結,包括它為什麼存在、它長怎麼樣、它的應用等等。

現在我們知道什麼是內部連結還有外部連結了,下一章我們會來介紹更進階的概念:名稱空間。

這樣我們下一章見啦!