C++ 基础

C++ 主页 C++ 概述 C++ 环境设置 C++ 基本语法 C++ 注释 C++ Hello World C++ 省略命名空间 C++ 标记 C++ 常量/字面量 C++ 关键字 C++ 标识符 C++ 数据类型 C++ 数字数据类型 C++ 字符数据类型 C++ 布尔数据类型 C++ 变量类型 C++ 变量作用域 C++ 多变量 C++ 基本输入/输出 C++ 修饰符类型 C++ 存储类 C++ 数字 C++ 枚举 C++ 枚举类 C++ 引用 C++ 日期和时间

C++ 运算符

C++ 运算符 C++ 算术运算符 C++ 关系运算符 C++ 逻辑运算符 C++ 位运算符 C++ 赋值运算符 C++ sizeof 运算符 C++ 条件运算符 C++ 逗号运算符 C++ 成员运算符 C++ 强制类型转换运算符 C++ 指针运算符 C++ 运算符优先级 C++ 一元运算符

C++ 控制语句

C++ 决策语句 C++ if 语句 C++ if else 语句 C++ 嵌套 if 语句 C++ switch 语句 C++ 嵌套 switch语句 C++ 循环类型 C++ while 循环 C++ for 循环 C++ do while 循环 C++ Foreach 循环 C++ 嵌套循环 C++ break 语句 C++ continue 语句 C++ goto 语句

C++ 字符串

C++ 字符串 C++ 循环遍历字符串 C++ 字符串长度 C++ 字符串连接 C++ 字符串比较

C++ 函数

C++ 函数 C++ 多函数参数 C++ 递归函数 C++ 返回值 C++ 函数重载 C++ 函数重写 C++ 默认参数

C++ 数组

C++ 数组 C++ 多维数组 C++ 指向数组的指针 C++ 将数组传递给函数 C++ 从函数返回数组

C++ 结构 &联合

C++ 结构 C++ 联合

C++ 指针

C++ 指针 C++ 解引用 C++ 修改指针

C++ 类和对象

C++ 面向对象 C++ 类 &对象 C++ 类成员函数 C++ 类访问修饰符 C++ 静态类成员 C++ 静态数据成员 C++ 静态成员函数 C++ 内联函数 C++ this 指针 C++ 友元函数 C++ 指向类的指针

C++ 构造函数

C++ 构造函数 &析构函数 C++ 默认构造函数 C++ 参数化构造函数 C++ 复制构造函数 C++ 构造函数重载 C++ 带默认参数的构造函数 C++ 委托构造函数 C++ 构造函数初始化列表 C++ 使用构造函数动态初始化

C++ 继承

C++ 继承 C++ 多重继承 C++ 多级继承

C++ 面向对象

C++ 重载 C++ 多态性 C++ 抽象 C++ 封装 C++ 接口 C++ 虚函数 C++ 纯虚函数与抽象类

C++ 文件处理

C++ 文件和流 C++ 文件读取

C++ 进阶

C++ 异常处理 C++ 动态内存 C++ 命名空间 C++ 模板 C++ 预处理器 C++ 信号处理 C++ 多线程 C++ Web 编程 C++ 套接字编程 C++ 并发 C++ 高级概念 C++ Lambda 表达式 C++ unordered_multiset

C++ 实用资源

C++ 问答 C++ 快速指南 C++ 速查表 C++ STL 教程 C++ 标准库 C++ 实用资源 C++ 讨论


C++ 中的命名空间

设想这样一种情况:同一个类中有两个同名的人,Zara。每当我们需要明确区分他们时,就必须使用一些附加信息,例如地区、他们是否居住在不同地区,或者他们父母的姓名等等。

同样的情况也可能出现在您的 C++ 应用程序中。例如,您可能正在编写一些包含名为 xyz() 的函数的代码,而另一个可用的库中也包含相同的函数 xyz()。现在,编译器无法知道您在代码中引用的是哪个版本的 xyz() 函数。

命名空间旨在解决这一难题,它用作附加信息来区分不同库中具有相同名称的类似函数、类、变量等。使用命名空间,您可以定义定义名称的上下文。本质上,命名空间定义了一个作用域。

定义命名空间

命名空间的定义以关键字 namespace 开头,后跟命名空间名称,如下所示 -

namespace namespace_name {
    // 代码声明
}

要调用启用命名空间的函数或变量版本,请在前面添加 (::) 命名空间名称,如下所示 -

name::code; // 代码可以是变量或函数。

让我们看看命名空间如何作用于包括变量和函数在内的实体 -

#include <iostream>
using namespace std;

// 名字空间
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// 第二个命名空间
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

int main () {
    // 从第一个命名空间调用函数。
    first_space::func();
    
    // 从第二个命名空间调用函数。
    second_space::func();
    
    return 0;
}

如果我们编译并运行上述代码,将产生以下结果 -

Inside first_space
Inside second_space

using 指令

您还可以使用 using namespace 指令避免在命名空间前添加前缀。该指令告知编译器后续代码正在使用指定命名空间中的名称。因此,以下代码隐含了该命名空间 -

#include <iostream>
using namespace std;

// 第一个命名空间
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// 第二个命名空间
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

using namespace first_space;
int main () {
   // 这从名字空间调用函数。
   func();
   
   return 0;
}

如果我们编译并运行上述代码,将产生以下结果 -

Inside first_space

using 指令也可用于引用命名空间内的特定项。例如,如果您打算使用的 std 命名空间中唯一部分是 cout,则可以按如下方式引用它 -

using std::cout;

后续代码可以引用 cout 而无需在前面添加命名空间,但 std 命名空间中的其他项仍需要按如下方式显式指定 -

#include <iostream>
using std::cout;

int main () {
   cout << "std::endl is used with std!" << std::endl;
   
   return 0;
}

如果我们编译并运行上述代码,将产生以下结果 -

std::endl is used with std!

using 指令中引入的名称遵循常规作用域规则。该名称从 using 指令处到该指令所在作用域的末尾均可见。在外部作用域中定义的同名实体将被隐藏。

不连续的命名空间

命名空间可以分为多个部分定义,因此命名空间由其单独定义的部分的总和组成。命名空间的各个部分可以分布在多个文件中。

因此,如果命名空间的某个部分需要另一个文件中定义的名称,则仍然必须声明该名称。编写以下命名空间定义可以定义新的命名空间或向现有命名空间添加新元素 −

namespace namespace_name {
   // 代码声明
}

嵌套命名空间

命名空间可以嵌套,您可以在一个命名空间内定义另一个命名空间,如下所示 -

namespace namespace_name1 {
    // 代码声明
    namespace namespace_name2 {
        // 代码声明
    }
}

您可以使用解析运算符访问嵌套命名空间的成员,如下所示 -

// 访问 namespace_name2 的成员
using namespace namespace_name1::namespace_name2;

// 访问 namespace:name1 的成员
using namespace namespace_name1;

如果在上述语句中使用了 namespace_name1,则 namespace_name2 中的元素将在作用域内可用,如下所示 -

#include <iostream>
using namespace std;

// 第一个名称空间
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
   
   // 第二个命名空间
   namespace second_space {
      void func() {
         cout << "Inside second_space" << endl;
      }
   }
}

using namespace first_space::second_space;
int main () {
    // 这会从第二个命名空间调用函数。
    func();
    
    return 0;
}

如果我们编译并运行上述代码,将产生以下结果 -

Inside second_space