Skip to content

Latest commit

 

History

History
203 lines (158 loc) · 4.92 KB

08.md

File metadata and controls

203 lines (158 loc) · 4.92 KB

文章内容

一.命名空间(namespace)在C++中的作用

二.定义一个命名空间

三.using关键字的使用

四.不连续的命名空间

五.多重嵌套的命名空间

命名空间在CPlusPlus中的作用

有这样一种情况,当一所学校同一班级有两个姓名相同的学生时,假设他们都叫张三,我们要分辨出这两个学生就需要添加额外的信息,比如来自河南的张三,来自河北的张三。这样就能够分别出这两个人了。

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

命名空间(namespace)就是为了克服这一困难而设计的,它被用作附加信息来区分不同库中具有相同名称的类似函数、类、变量等。本质上,名称空间定义了一个范围,有着封装和解决命名冲突这两个好处。

定义一个命名空间

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

namespace TestNamespace
{
    int x;
    void f() {};
}
// 为了调用包含在`namespace`的函数或变量,需要做以下示例操作
int main()
{
    TestNamespace::x;
    TestNamespace::f();
}

接下来看看怎么使用命名空间范围内的函数,变量等实体的,如下所示:

#include <iostream>

namespace FirstTest
{
    int x;
    void func()
    {
        std::cout << "In First Test!" << std::endl;
    }
}

namespace SecondTest
{
    int x;
    void func()
    {
        std::cout << "In Second Test!" << std::endl;
    }
}

int main()
{
    // 调用FirstTest里的func函数
    FirstTest::func();
    FirstTest::x = 3;

    // 调用SecondTest里的func函数
    SecondTest::func();
    SecondTest::x = 5;

    std::cout << FirstTest::x << " " << SecondTest::x;
    return 0;
}
//OUTPUT
/*
In First Test!
In Second Test!
3 5
*/

using关键字的使用

使用using namespace可避免使用namespace指令将名称空间作为前缀。此指令告诉编译器后续代码使用指定名称空间中的名称。命名空间因此被隐含在下面的代码中

#include <iostream>

namespace FirstTest
{
    int x;
    void func()
    {
        std::cout << "In First Test!" << std::endl;
    }
}

namespace SecondTest
{
    int x;
    void func()
    {
        std::cout << "In Second Test!" << std::endl;
    }
}
using namespace FirstTest;
int main () {
   // 调用FirstTest里的func函数
   func();
   
   return 0;
}
// 编译并运行上述代码,这将产生以下结果
/*
In First Test!
*/

using指令也可以用来引用命名空间中的特定项。例如,如果你打算使用的标准库(标准库的命名空间为std)std中的cout一个函数,那么可以如下所示引用它

#include <iostream>
using std::cout;

int main()
{
    cout << "std::endl is used with std! but cout not!" << std::endl;

    return 0;
}
// OUTPUT
/*
std::endl is used with std! but cout not!
*/

这里做一点补充,using在c++中还可以当做C语言typedef的作用定义一个新的类型。

注: 通过using指令中引入的名称符合正常的范围规则。从using指令的角度来说名称在指令的整个作用域(生命周期内)(开始和末尾)都可见。但是外部范围中定义的同名实体其实应该是隐藏的。

不连续的命名空间

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

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

多重命名空间

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

namespace Name1
{
    namespace Name2
    {

    }
}

// 可以使用如下操作符访问嵌套名称空间的成员
// 访问Name2的成员
using namespace Name1::Name2;
// 访问Name1的成员
using namespace Name1;

在上面的语句中,如果使用using Name1,那么它将使Name2的元素在作用域中可用,如下所示

#include <iostream>
using namespace std;

namespace Name1 
{
   void func() 
   {
      cout << "Inside Name1's space" << endl;
   }
   
   namespace Name2 
   {
      void func() 
      {
         cout << "Inside Name2's space" << endl;
      }
   }
}

using namespace Name1;
int main () {
   
    func();
    // 这将从第二个名称空间调用函数。
    Name2::func();
   return 0;
}
// OUTPUT
/*
Inside Name1's space
Inside Name2's space
*/