当这些全局变量具有命名空间范围时,为什么它们是全局变量?

Wan*_*ool 1 c++ scope namespaces global-variables forward-declaration

在下面的代码中,是调用 globals.cpp 命名空间中的变量实际全局变量

全局变量.h

#ifndef GLOBALS_H_
#define GLOBALS_H_

namespace Constants
{
    // forward declarations only
    extern const double pi;
    extern const double avogadro;
    extern const double my_gravity;
}

#endif
Run Code Online (Sandbox Code Playgroud)

全局变量.cpp

namespace Constants
{
    // actual global variables
    extern const double pi(3.14159);
    extern const double avogadro(6.0221413e23);
    extern const double my_gravity(9.2); // m/s^2 -- gravity is light on this planet
}
Run Code Online (Sandbox Code Playgroud)

源代码.cpp

#include <iostream>
#include <limits>

#include "globals.h"

int main()
{
    double value_of_pi = Constants::pi;

    std::cout << value_of_pi;

    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    std::cin.get();

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

我知道它extern用于访问其他翻译单元中的全局变量。我可能读得太多了,但是为什么当 globals.cpp 命名空间中的变量具有命名空间范围时,它们被认为是全局的?另外,我是否可以假设从 globals.h 命名空间中的前向声明中Constants::pi检索标识符?pi

这个问题是我在这里提出的上一个问题的延续

vso*_*tco 5

全局大致意味着可以从每个翻译单元访问,无论变量是否位于名称空间中。最好的例子是std::cout,它是 中定义的全局变量namespace std,代表 的实例化std::basic_ostream<>

关于你的第二个问题,Constants::pi可以访问,因为你包含了 header globals.h,它声明了extern const double Constants::pi;. 此声明指示编译器该变量具有外部链接,您有责任在某个.cpp文件中定义它(您在1)globals.cpp中进行定义。因此链接器能够在 中找到该符号,仅此而已。globals.cpp


1) 请注意,您甚至可以直接在头文件中提供定义extern const double pi = 3.14;,但不建议这样做,因为在多个翻译单元中包含头将导致重复符号。

  • 太感谢了!现在这个世界在我看来变得更有意义了。 (2认同)