全局范围与全局命名空间

scd*_*dmb 59 c++ scope namespaces terminology

我看到了这两个短语的用法:全局范围和全局命名空间.他们之间有什么区别?

Naw*_*waz 83

在C++中,每个名称的范围都不在其中.范围可以通过多种方式定义:它可以由命名空间,函数, {}来定义.

因此,全局或其他命名空间定义范围.全局命名空间指的是使用::,并且该命名空间中定义的符号被称为具有全局范围.默认情况下,符号存在于全局命名空间中,除非它在块中以关键字开头定义namespace,或者它是类的成员或函数的局部变量:

int a; //this a is defined in global namespace
       //which means, its scope is global. It exists everywhere.

namespace N
{
     int a;  //it is defined in a non-global namespace called `N`
             //outside N it doesn't exist.
}
void f()
{
   int a;  //its scope is the function itself.
           //outside the function, a doesn't exist.
   {
        int a; //the curly braces defines this a's scope!
   }
}
class A
{
   int a;  //its scope is the class itself.
           //outside A, it doesn't exist.
};
Run Code Online (Sandbox Code Playgroud)

另请注意,名称可以由命名空间,函数或类定义的内部作用域隐藏.因此a命名空间内的名称会N隐藏a全局namspace中的名称.同样,函数和类中的名称隐藏了全局命名空间中的名称.如果您遇到这种情况,那么您可以使用它::a来引用全局命名空间中定义的名称:

int a = 10;

namespace N
{
    int a = 100;

    void f()
    {
         int a = 1000;
         std::cout << a << std::endl;      //prints 1000
         std::cout << N::a << std::endl;   //prints 100 
         std::cout << ::a << std::endl;    //prints 10
    }
}
Run Code Online (Sandbox Code Playgroud)


Mik*_*our 7

“范围”是比“命名空间”更通用的术语。每个命名空间、类和代码块都定义了一个作用域,在该作用域中可以使用在其中声明的名称;命名空间是在类和函数之外声明的名称的容器。

“全局范围”和“全局命名空间”或多或少可以互换使用;在命名空间中声明的名称的范围涵盖了整个命名空间。如果您特指命名空间,请使用“命名空间”,如果您指的是其中名称的可见性,请使用“范围”。


dry*_*jov 7

作用域表示对象的生命周期,您可以拥有一个只要程序执行就存在的全局变量,也可以拥有一个具有块作用域的变量,只要该代码块执行,它就存在。考虑这个例子:

#include <iostream>

int a = 100;

main () {
    int a = 200;

    std::cout << "local a is: " << a << std::endl;
    std::cout << "global a is: " << ::a << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

执行时,该语句将打印local a is: 200,这显然是预期的,因为我们正在重新定义其封闭块范围内的哪些叶子amain我们还打印了 global ::a,它再次打印了期望值 100 ,因为我们已经请求了全局命名空间::

命名空间语义主要是逻辑性的,它是一种将符号彼此隔离的方式,希望避免名称冲突,它不会影响对象的生命周期。

另一方面,作用域表示对象的生命周期,全局对象a在局部对象之前出现a,因为它的构造比 main 的执行早得多。然而,作用域也会在符号上强制命名空间,但与 a 的方式不同namespace。有不同类型的范围global,,,,,等等......classfunctionblockfile

令人困惑的部分是,作用域有时会被重载以表示特定符号的可见性,这是​​从 C 借来的,其中命名空间的概念不存在,作用域用于表示生命周期和可见性。然而,在 C++ 中,规则发生了一些变化,但术语作用域的使用方式仍然相同,因为这两种语言共享很多概念。


Eri*_*c Z 6

int i例如,当您声明一个全局变量时,我们说i is in the global namespacehas the global namespace scope。就这样。

摘自 C++03:

3.3.5 Namespace scope   

    The outermost declarative region of a translation unit is also a namespace, called
  the global namespace. A name declared in the global namespace has global namespace
  scope (also called global scope).
Run Code Online (Sandbox Code Playgroud)