C++ 中的名稱空間

Jinku Hu 2023年1月30日 2021年6月28日
  1. 使用 namespace 關鍵字在 C++ 中建立新的名稱空間
  2. 使用巢狀名稱空間在 C++ 中實現複雜的作用域
C++ 中的名稱空間

本文將解釋如何在 C++ 中使用名稱空間。

使用 namespace 關鍵字在 C++ 中建立新的名稱空間

C++ 具有名稱空間的概念,有助於防止大型專案中稱為名稱衝突的常見問題。當給定的專案使用獨立團隊開發的不同庫,並且不同物件有很多全域性名稱時,不可避免地會出現一些名稱匹配並導致錯誤的情況。名稱空間宣告瞭一個範圍,其中定義了某些函式或其他物件的名稱。請記住,C++ 中有自動作用域規則,用於控制物件名稱在不同程式碼區域中的顯示方式和可用方式。例如,函式中宣告的區域性變數在函式體之外是看不到或不可訪問的。因此,可以在此函式的主體之外宣告另一個同名變數,而不會產生任何衝突。另一方面,我們有一個單一的全域性作用域,大型程式經常使用它來使某些物件跨檔案或函式可用。現在,想象一下如何管理沒有任何手動範圍機制的空間。

事實上,程式設計師過去常常使用非常長的全域性物件名稱來處理名稱衝突。它可以適用於相對較小的專案,但它使程式碼閱讀起來非常混亂,並且解決方案在沒有協調命名方案的情況下仍然無法防止名稱衝突。
名稱空間提供了一種劃分全域性範圍(因此稱為名稱空間)的機制。名稱空間是用 namespace 關鍵字後跟名稱空間名稱本身來宣告的。然後跟在與功能塊類似的花括號中的程式碼之後,它結束時沒有分號。與程式碼的其他部分相同的自動範圍規則管理名稱空間內的變數。需要從名稱空間外部訪問的物件名稱需要以定義它們的名稱空間名稱開頭,後跟雙冒號符號,然後是物件名稱。以下程式碼示例演示了基本用例 where for the namespaces in the same file。

#include <iostream>

using std::cout; using std::endl;

namespace dinno {
    int var1 = 456;
}

int main()
{
    int var1 = 123;

    cout << var1 << endl;
    cout << dinno::var1 << endl;

    return EXIT_SUCCESS;
}

輸出:

123
456

使用巢狀名稱空間在 C++ 中實現複雜的作用域

名稱空間可以巢狀,類似於迴圈語句。預設情況下,巢狀名稱空間可以訪問外部名稱空間中的物件名稱,但後者(通常稱為父名稱空間)無法訪問內部名稱空間中的成員。雖然,可以在內部名稱空間宣告之前指定關鍵字 inline,使其成員可以在父名稱空間中訪問。名稱空間可以在不同的地方定義。即,相同的名稱空間定義可以跨越不同的檔案或單個檔案中的不同位置,因為在以下示例中定義了 dinno 名稱空間。

#include <iostream>

using std::cout; using std::endl;

namespace dinno {
    int var1 = 456;
}

namespace gini {
    int var1 = 980;

    namespace bean {
        int var1 = 199;
    }
}

namespace dinno {
    int var2 = 990;
}

int var1 = 123;

int main()
{
    cout << var1 << endl;
    cout << dinno::var1 << endl;
    cout << gini::var1 << endl;
    cout << dinno::var2 << endl;
    cout << gini::bean::var1 << endl;

    return EXIT_SUCCESS;
}

輸出:

123
456
980
990
199
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn