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

原文:https://www.studytonight.com/cpp/namespace-in-cpp.php

命名空间是标识符的容器。它将其成员的名称放在不同的空间中,这样它们就不会与其他名称空间或全局名称空间中的名称冲突。


创建命名空间

创建命名空间类似于创建类。

namespace MySpace
{
    // declarations
}

int main() 
{
    // main function
}

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


创建命名空间的规则

  1. 命名空间定义必须在全局范围内完成,或者嵌套在另一个命名空间内。
  2. 命名空间定义不像类定义那样以分号结束。
  3. You can use an alias name for your namespace name, for ease of use.

    别名示例:

    namespace StudyTonightDotCom
    {
        void study();
        class Learn 
        {  
            // class defintion
        };
    }
    
    // St is now alias for StudyTonightDotCom
    namespace St = StudyTonightDotCom;
    
  4. 您不能创建命名空间的实例。

  5. There can be unnamed namespaces too. Unnamed namespace is unique for each translation unit. They act exactly like named namespaces.

    未命名命名空间示例:

    namespace
    {
        class Head 
        { 
            // class defintion
        };
        // another class
        class Tail 
        { 
            // class defintion
        };
        int i,j,k;
    }
    
    int main() 
    { 
        // main function
    }
    
  6. A namespace definition can be continued and extended over multiple files, they are not redefined or overriden.

    例如,下面是一些头 1.h 头文件,我们在其中定义了一个名称空间:

    namespace MySpace
    {
        int x;
        void f();
    }
    

    然后,我们可以将头 1.h 头文件包含在其他一些头 2.h 头文件中,并向现有名称空间添加更多内容:

    #include "header1.h";
    
    namespace MySpace
    {
        int y;
        void g();
    }
    

在 C++ 中使用命名空间

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

  1. 范围解析运算符(::)
  2. using指令
  3. using宣言

带范围解析运算符(::)

命名空间中声明的任何名称(标识符)都可以使用命名空间的名称和带有标识符的范围解析::运算符来显式指定。

namespace MySpace
{
    class A
    {
        static int i;
        public:
        void f();
    };

    // class name declaration
    class B;    

    //gobal function declaration
    void func();   
}

// Initializing static class variable
int MySpace::A::i=9;      

class MySpace::B
{
    int x;
    public:
    int getdata()
    {
        cout << x;
    }
    // Constructor declaration
    B();   
}

// Constructor definition
MySpace::B::B()   
{
    x=0;
}

using指令

using关键字允许您将整个命名空间导入到具有全局范围的程序中。它可以用来将一个命名空间导入到另一个命名空间或任何程序中。

包含头文件命名空间 1.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;
    // creating object of class Check
    Check obj2;
}

因此,using指令使得在任何地方使用名称空间变得更加容易。


using宣言

当我们使用using指令时,我们导入名称空间中的所有名称,它们在整个程序中都是可用的,也就是说它们有一个全局范围。

但是通过using声明,我们一次导入一个特定的名称,该名称仅在当前范围内可用。

:用using声明导入的名称可以覆盖用using指令导入的名称

考虑一个文件命名空间。

namespace X
{
    void f()
    {
        cout << "f of X namespace\n";
    }
    void g() 
    {
        cout << "g of X namespace\n";
    }
}

namespace Y
{
    void f()
    {
        cout << "f of Y namespace\n";
    }
    void g() 
    {
        cout << "g of Y namespace\n";
    }
}

现在我们用下面的代码创建一个名为 program2.cpp 的新程序文件:

#include "Namespace.h";

void h()
{
    using namespace X;  // using directive
    using Y::f; // using declaration
    f();    // calls f() of Y namespace
    X::f(); // class f() of X namespace
}

命名空间的 f

在使用声明时,我们在导入函数时从不提及它的参数列表,因此如果一个命名空间重载了函数,就会导致歧义。