C++ 全局作用域与全局命名空间

C++ 全局作用域与全局命名空间,c++,namespaces,scope,terminology,C++,Namespaces,Scope,Terminology,我看到了这两个短语的用法:全局范围和全局名称空间。它们之间的区别是什么? 在C++中,每个名称都有其范围之外,它不存在。作用域可以通过多种方式定义:它可以通过名称空间、函数、类和{}来定义 因此,名称空间(全局或其他)定义了一个范围。全局名称空间指使用:,在该名称空间中定义的符号称为具有全局作用域。默认情况下,符号存在于全局命名空间中,除非它是在以关键字命名空间开头的块中定义的,或者它是类的成员,或者是函数的局部变量: int a; //this a is defined in global n

我看到了这两个短语的用法:全局范围和全局名称空间。它们之间的区别是什么?

在C++中,每个名称都有其范围之外,它不存在。作用域可以通过多种方式定义:它可以通过名称空间、函数、类和{}来定义

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

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.
};
还要注意,名称可以由命名空间、函数或类定义的内部范围隐藏。因此名称
a
在名称空间
N
中隐藏了全局名称空间中的名称
a
。同样,函数和类中的名称隐藏全局命名空间中的名称。如果遇到这种情况,则可以使用
::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
    }
}
inta=10;
名称空间N
{
INTA=100;
void f()
{
INTA=1000;

std::cout例如,当您声明一个全局变量
int i
时,我们说
i在全局名称空间中
具有全局名称空间范围
。仅此而已

摘自C++03:

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


“全局作用域”和“全局命名空间”可以或多或少地互换使用;命名空间中声明的名称的作用域涵盖该命名空间的整个范围。如果您特别指的是命名空间,请使用“命名空间”和“作用域”如果你指的是它里面名字的可见性,

范围表示一个对象的生命周期,你可以有一个全局变量,只要你的程序执行,它就可以存在,或者你可以有一个块范围的变量,只要这个代码块执行,就可以存在。
#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;
}
#包括
INTA=100;
主要(){
INTA=200;
std::cout@Dmitriy Ryajov

这个话题有点老了,但我想在这方面提供我的帮助。我认为你不应该把事情弄得比实际情况更复杂。
标识符的作用域
是计算机程序的一部分,在这个程序中,标识符(指程序中某个实体的名称)可以用来找到所指的实体。因此术语scope仅适用于标识符,我们不应将其与对象的生存期混为一谈。它们之间有一定的联系,但不应混为一谈。对象的生存期由我们为该对象分配内存的位置表示。因此,例如,如果在堆栈上分配内存,则该内存将在函数完成后立即释放。因此结束于我们存储对象的位置,这表示对象的生存期。作用域仅表示:“这里是对象的名称,我们可以使用该名称来表示对象,直到那时”。因此,正如我所说的,术语
scope
仅用于对象的标识符,而生存期是由我们存储对象的位置表示的其他内容

此外,我想说一些与此密切相关的
链接
。这有时也会令人困惑。假设我们在
翻译单元
中有一些标识符,它们引用一些对象。表示
其他
翻译单元中的相同标识符是否引用相同的实体因此,例如,如果一个标识符有一个外部链接,我们可以通过使用关键字
extern
声明它来引用该标识符所引用但来自其他翻译单元的实体。现在,假设我们不想在其他翻译单元中使用该实体。然后,该实体将
存在
,直到程序运行m完成,但当我们不声明它时,我们将无法引用它。还要注意,现在我混合了术语“链接”和“生存期”。但这是因为只有
global
实体具有外部链接。函数中的标识符不能从程序的其他部分引用


结论:总是尽量保持简单。我很惊讶不同的人对这些术语的说法是不同的。单独编译的整个过程令人困惑,因为有多个术语的含义几乎相同,可能每个人都会在这一点上陷入困境。

很好,你强调了范围是对象生命周期所固有的。如果我们想访问函数void f()中的“a”(在命名空间N中定义){}@rimiro:如果在函数作用域中声明了
a
,您不能从函数外部访问它。那么命名空间就是作用域的一种吗?@JozefMikušinec..Yes:-)
#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;
}