C ++允许重新定义全局(const)变量?

时间:2013-10-11 14:13:24

标签: c++ const global redeclaration

我对全局常量感到有点困惑。我(初学者级别)的理解是'全局'变量是在块之外定义的并且具有程序范围(来源:http://www.learncpp.com/cpp-tutorial/42-global-variables/)。但该计划:

#include <iostream>

const double x=1.5;

int main(){
        std::cout << "1) x=" << x << std::endl;
        double x=2.5;
        std::cout << "2) x=" << x << std::endl;
        //const double x=3.5;
        return 0;
}

使用-Wall编译g ++(GCC,最新的64位版本),没有任何问题。

输出:

1) x=1.5
2) x=2.5

这让我感到困惑。第一个cout评估的事实意味着main将'x'识别为'全局'变量(它没有在main的范围中定义)。如果是这样的话,为什么让我重新定义'x'?

然后,如果取消注释注释的第三个声明,g ++会引发重新声明错误。意思是,我的第一个宣言不能是'全球',在我定义的意义上:S

编辑:好的,问题与全局变量无关,但是范围:例如http://pastebin.com/raw.php?i=V5xni19M中的同样问题

6 个答案:

答案 0 :(得分:8)

#include <iostream>

const double x=1.5;

在代码的这一点上,全局范围内有一个名为x的对象,它的类型为const double

int main(){
        std::cout << "1) x=" << x << std::endl;

此时,仍然只有一个x可见(全局一个),因此这就是x所指的名称。

        double x=2.5;

在代码的这一点上,您已将名为x的对象引入main()的范围。该范围嵌套在全局范围内,因此现在您有两个名为x的对象:

    全局范围x

    中的
  1. const double 类型为x

    的<{1}}范围内的
  2. main()

  3. 本地double隐藏了全局x。如果您想访问x内的全局x,可以将其称为main()

    ::x

    您是否尝试将名为 std::cout << "2) x=" << x << std::endl; double x=3.5; //uncommented 另一个对象引入x的范围。这是不可能的,该范围内已有一个main(),因此失败。

答案 1 :(得分:1)

第二个x不是重新定义。全球hidingx。 这是值得关注的事情,特别是在处理继承时:

  struct Base 
  {
      void AwesomeFunction() { }
  };

  struct Derived : public Base
  {
      // This definition 'hides' Base::AwesomeFunction
      void AwesomeFunction() { }
  };

仅允许隐藏,因为第二个x的范围小于全局x。 你得到第三个x的redfinition错误,因为第三个和第二个x处于同一范围'level'。

答案 2 :(得分:1)

使用:: x从程序中访问全局变量。现在你正在创建一个局部变量和一个全局变量。当你第一次打印x时,它找不到本地的,所以它假定你的意思是全局的。制作本地x后,它不再默认为全局。

答案 3 :(得分:1)

代码中发生的情况是,如果局部变量占用相同的名称,则它优先于全局变量。您可以在整个程序的任何块中使用全局变量,而本地变量将在其块(主)的末尾处理。但是,编译器不允许在一个块中声明两个同名的局部变量。

答案 4 :(得分:1)

内部作用域(如main)的声明允许在外部作用域(如文件作用域)中进行 shadow 声明。你的第三个x声明与你的第二个声明的范围相同,因此这是一个重新声明错误。

答案 5 :(得分:1)

你没有重新定义全局变量;你要定义一个具有相同名称的单独局部变量。

C ++允许您重用一个名称来在像这样的较窄范围内声明其他内容;从技术上讲,内部作用域中的声明隐藏外部作用域中的声明,以便在声明和函数结尾之间x引用局部变量。您仍然可以通过使用其命名空间限定它来访问全局变量:::x

第三个声明将尝试在同一范围内重用该名称,这是不允许的。