C++名称空间简介

149 阅读6分钟

C++名称空间简介

一个名字在每个作用域中只能代表一个实体。这就是为什么在同一个作用域中,不能有两个同名的变量,因为这可能会产生编译器错误。我们可以使用namespace ,在同一作用域内声明两个具有相同名称的变量或成员函数。

这将导致几个函数具有相同的名称,我们可以通过引用命名空间的名称从程序中的任何地方访问所有的函数。本文将介绍命名空间以及它们在C++中的使用方法。

前提条件

要学习这篇文章,你需要具备以下条件。

  • 用于运行代码的[Codeblocks IDE]。
  • 对C++语言有基本的了解。
  • 对C++函数有基本的了解。

什么是命名空间?

命名空间指的是可以在程序中创建的各种块,用来分组所有类似的对象,你可以在一个块中指代所有的变量、函数或类。

命名空间声明的一些特点是。

  • 命名空间的声明只在全局范围内出现。
  • 在另一个命名空间内嵌套命名空间声明是可能的。
  • 命名空间声明没有权限标签(private、public和protected),因为它们是在全局范围内声明的,可以很容易地嵌套到其他命名空间中。
  • 命名空间定义不需要在结尾的大括号后面加上分号。
  • 命名空间的定义可以分为多个单元。
  • 对于同一个名字,允许有多个命名空间的声明块。在命名范围内的这些块内是所有声明的地方。

命名空间声明的语法。

命名空间是一个声明性区域,它为不同的函数和变量指定了不同的范围,所以当人们要引用一个这样的变量函数时,我们可以使用命名空间的名称。

namespace namespacename 
{
   int m, n; // code declarations where 
             // m and n are declared in 
             // namespace_name's scope
}

让我们来分解一下语法。

  • namespace - 是用于声明命名空间的关键字。
  • namespacename - 是给命名空间的名称。
  • int m, n - 是命名空间_名称的范围内的变量。

我们使用范围解析操作符:: 来访问特定命名空间中的变量,如下所示。

namespace_name :: variablename
Namespace_name :: functionname

命名空间如何在C++中工作

当使用关键字namespace 来声明一个名字空间时,在该名字空间内声明的所有函数、变量或类都属于该范围,可以使用该名字空间的name 与范围解析操作符:: 来引用。

编译器在遇到范围解析操作符:: ,就会将控制发送到命名空间块。一个命名空间也可以在多个作用域中定义,如果一个命名空间是未命名的,那么其中指定的变量和函数可以以访问全局变量的方式显式访问。

一些命名空间中的命名空间也可能是嵌套的。为了访问它们,我们需要使用范围解析操作符:: 操作符的次数来访问它们。

比如说。

namespace example1 {
  namespace example2 {
    namespace example3 {
      int sample;
    }
  }
}

当我们想访问变量sample ,我们需要使用example1::example2::example3::sample

通过这一点,我们可以制作独立的作用域,并在程序中重复使用存在于不同命名空间的相同变量名。命名空间的使用使我们能够处理多个库中的文件。

到目前为止,无论何时我们决定使用一个命名空间,我们都必须通过在作用域解析操作符前包括命名空间标识符来引用命名空间的函数。然而,通过使用using-指令,并使用如下所示的语法,你可以在一段代码中插入整个命名空间。

using namespace namespacename;

这允许开发者从命名空间内调用函数,而不需要在当前范围内定义函数的命名空间。

通常情况下,如果你不在一个代码块内,在下一个闭合括号之前,或者整个文件中。这种简单性可以通过全局使用命名空间来加以利用,这与使用命名空间的一些原因相矛盾。

这种使用最常见的例子是。using namespace std;,它被用来访问名为标准的命名空间,其中包括C++ I/O对象coutcin

例子1

说明命名空间工作的程序。

#include<iostream>
//Importing the  namespace standard
using namespace std;
//Creating namespaces
namespace no1 {
  int fun() {
    return 10;
  }
}

namespace no2 {
  //Declaring a variable in the namespace
  const double x = 200;
  //Function definition within the namespace
  double fun() {
    return 2 * x;
  }
}

namespace no3 {
  // Creating a class in the namespace
  class sample {
    public:
      void show() {
        cout << "no3::sample::show()\n";
      }
  };
}

int main() {

  // Accessing the function within namespace no1
  cout << no1::fun() << '\n';
  // Accessing the function within namespace no2
  cout << no2::fun() << '\n';
  // Accessing the variable x directly
  cout << no2::x << '\n';
  // Creating an object of class sample
  no3::sample myObj;
  myObj.show();
  return 0;
}

输出。

10
400
200
no3::sample::show()

在上面的程序中,我们在两个不同的命名空间,no1no2 ,描述了同一个函数名称。我们还在另一个命名空间no3 中定义并访问了类sample

正如我们前面提到的,为了访问不同命名空间的函数,我们使用了范围解析操作符:: 。如程序所示,我们可以通过使用操作符no1::fun() 来访问函数fun()

例2

程序说明了同名空间的工作情况。

#include <iostream>

using namespace std;
// Creating namespaces with the same name
namespace sample {
  // Declaring variable x within the namespace
  int x = 20;
}

namespace sample {
  //Declaring variable y within the namespace
  int y = 50;
}
// Creating unnamed namespace
namespace {
  //Declaring and initializing a variable
  int a = 15;
  // Function definition within the unnamed namespace
  int fun() {
    return a;
  }
}

int main() {
  // Accessing the variable x within the namespace sample
  cout << "Value of x = " << sample::x << '\n';
  // Accessing the variable y within the namespace sample
  cout << "Value of y = " << sample::y << '\n';
  // Accessing the function within the unnamed namespace
  cout << "Value returned by the unnamed namespace = " << fun() << '\n';
  return 0;
}

输出。

Value of x = 20
Value of y = 50
Value returned by the unnamed namespace = 15

在上面的程序中,我们可以看到我们如何创建几个同名的名字空间。sample 这个名字已经被两个拥有不同变量的名字空间所使用。因此,我们的变量在同一个范围内,在这两个范围内。我们还可以看到如何定义未命名的名字空间并访问函数fun()

例3

说明嵌套命名空间的程序。

#include <iostream>

using namespace std;
//Creating nested namespaces
namespace no1 {
  // Declaring variable within the namespace no1
  int sample = 10;
  namespace no2 {
    namespace no3 {
      // Declaring variable within the namespace no3 
      // that initializes to the variable sample in namespace no1
      int sample1 = sample;
    }
  }
}
//Creating namespace that allows us to use it explicitly to access a variable in the nested namespace
namespace myalias = no1::no2::no3;
//Creating namespace demo and declaring an initialized variable
namespace demo {
  int gvar = 200;
}
//Inserting the entire namespace demo into our code
using namespace demo;

int main() {
  //Accessing the variable without the scope resolution operator as it is a global namespace
  cout << "Value of global variable in demo namespace = " << gvar << "\n";
  //Accessing the value of sample1 using the namespace myalias
  cout << "Value of sample1 in nested namespace third = " << myalias::sample1 << "\n";
  return 0;
}

输出。

Value of global variable in demo namespace = 200
Value of sample1 in nested namespace third = 10

在上面的程序中,我们可以看到嵌套的名字空间是如何声明和从名字空间外部访问的。我们还演示了在没有范围解析操作符:: ,并使用using 指令的情况下访问命名空间中的变量。我们还看到了我们如何创建命名空间myalias ,使我们能够使用别名的名称明确地使用它。

命名空间的优点

  • 在一个程序中,命名空间可以帮助定义不同的范围,为其中声明的不同标识符提供范围。
  • 通过使用命名空间--相同的变量名可以在不同的程序中重复使用。
  • 库的使用--命名空间和命名空间对一起使用这两个库有很大帮助,使用范围解析操作符定义名称,有助于确定我们试图访问的变量。

总结

通过上面的例子,我们已经看到了在我们的程序中使用命名空间的好处。通过使用命名空间,我们可以防止在同一程序中出现相同变量名和函数名的文件冲突。在不同的文件和库中使用命名空间来定义相同的代码,可以增加我们代码的可读性。