C++ 命名空间



在 C++ 中创建和使用命名空间

命名空间是id名的容器,我们可以将一些数据或函数放在不同的命名空间中,这样它们就不会与其他命名空间或全局命名空间中的名称冲突。



创建命名空间

创建命名空间和创建类的方法类似。

namespace MySpace
{
    // 声明一些数据或函数
}

int main() 
{
    // 主函数
}

这将创建一个名为 MySpace 的新命名空间,我们可以在其中放置我们的成员。

创建命名空间的规则

  • 命名空间定义必须在全局范围内完成,或者嵌套在另一个命名空间内。
  • 命名空间定义不像类定义那样以分号结尾。
  • 你可以为你的命名空间名称使用别名,以方便使用。 别名示例:
namespace YetaoziDotCom
{
    void study();
    class Learn 
    {  
        // 声明类
    };
}

// St现在是YetaoziDotCom的别名
namespace St = YetaoziDotCom;
  • 命名空间不能用来实例化。
  • 也可以有 未命名 的命名空间,未命名的命名空间对于每个模块都是唯一的,它们的行为与有名字的命名空间完全一样。 未命名命名空间示例:
namespace
{
    class Head 
    { 
        // 类
    };
    // 另一个类
    class Tail 
    { 
        // 类
    };
    int i,j,k;
}

int main() 
{ 
    // 主函数
}
  • 命名空间定义可以在其他文件上追加和扩展,它们不会被重新定义或覆盖。 例如,下面是 header1.h 头文件,我们在其中定义了一个命名空间:
namespace MySpace
{
    int x;
    void f();
}

然后,我们可以将 header1.h 头文件包含在另一个 header2.h 头文件中,并向现有命名空间添加更多内容:

#include "header1.h";

namespace MySpace
{
    int y;
    void g();
}


在 C++ 中使用命名空间

在程序中使用命名空间有三种方式,

  • 范围解析运算符(::)
  • using 指令
  • using 声明

使用范围解析运算符 (::)

在命名空间中声明的任何成员都可以通过命名空间的名称和范围解析 :: 运算符调用

namespace MySpace
{
    class A
    {
        static int i;
    public:
        void f();
    };
    
    // 声明一个类
    class B;    
    
    // 一个函数
    void func();   
}

// 初始化类的静态成员变量
int MySpace::A::i=9;      

class MySpace::B
{
    int x;
public:
    int getdata()
    {
        cout << x;
    }
    // 声明构造函数
    B();   
}

// 定义构造函数
MySpace::B::B()   
{
    x=0;
}

using 指令

using 关键字允许你在某个范围内默认使用命名空间,它可用于将命名空间导入到另一个命名空间或其他地方。

比如我们有一个头文件 Namespace1.h

namespace X
{
    int x;
    class Check
    {
        int i;
    };
}

Namespace2.h 文件中包含上面的头文件:

include "Namespace1.h";

namespace Y
{
    using namespace X;
    Check obj;
    int y;
}

我们将命名空间 X 导入命名空间 Y,因此类 Check 现在将在命名空间 Y 中可用。

因此我们可以在文件中编写以下程序,如program1.cpp

#include "Namespace2.h";

void test()
{
    using Namespace Y;
    // 实例化类Check的对象
    Check obj2;
}

因此,using 指令使得在任何地方使用命名空间变得简捷方便。

using 声明

当我们使用 using 指令时,我们导入命名空间中的所有名称,并且它们在整个程序中都可用,即它们具有全局范围。

而当使用 using 声明时,我们可以一次导入一个特定名称,该名称仅在当前范围内可用。

注意:使用 using 声明导入的名称可以覆盖使用 using 指令导入的名称, 比如有一个文件 Namespace.h

namespace X
{
    void f()
    {
        cout << "命名空间X中的函数f()\n";
    }
    void g() 
    {
        cout << "命名空间X中的函数g()\n";
    }
}

namespace Y
{
    void f()
    {
        cout << "命名空间Y中的函数f()\n";
    }
    void g() 
    {
        cout << "命名空间Y中的函数g()\n";
    }
}

现在让我们使用以下代码创建一个名为 program2.cpp 的文件:

#include "Namespace.h";

void h()
{
    using namespace X;  // using 指令
    using Y::f; // using 声明
    f();    // 此时Y的f()覆盖了X的f()
    X::f(); // 调用X的f()
}

以上实例输出结果:

命名空间Y中的函数f()
命名空间X中的函数f()

在 using 声明中,我们还可以使用重载函数,请看如下示例:

#include <iostream>
using namespace std;

namespace X {
	void test()
	{
		cout << "test()\n";
	}
	void test(int x) 
	{
		cout << "test(int x)\n";
	}
}
int main()
{
	using X::test;
	test();
	test(2);
	return 0;
}

以上实例输出结果:

test()
test(int x)