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