为什么这些全局变量具有命名空间范围?

时间:2015-05-29 01:25:38

标签: c++ namespaces scope global-variables forward-declaration

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

globals.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

globals.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
}

source.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;
}

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

此问题是我提出的上一个问题的延续 here

1 个答案:

答案 0 :(得分:4)

全局粗略意味着可以从每个翻译单元访问,无论变量是否在命名空间中。最好的示例是std::cout,它是namespace std中定义的全局变量,它表示std::basic_ostream<>的实例化。

关于您的第二个问题,Constants::pi是可访问的,因为您包含标头globals.h,后者声明extern const double Constants::pi;。该声明指示编译器该变量具有外部链接,您有责任在某个.cpp文件(您在globals.cpp 1)中定义它。所以链接器能够在globals.cpp中找到符号,并且它就是它。

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