在课堂上宣布的名称评估顺序

时间:2013-05-03 15:31:07

标签: c++ scope

有这段代码:

#include <iostream>

const int c = 3;

struct A {
   static int f() { return c; }
   static const int c = 2;
};

int main() {
   std::cout << A::f() << std::endl; // 2
   return 0;
}

如何在函数c中使用变量A定义内部f而不是在全局范围内定义的变量c虽然首先声明了全局变量c吗?

3 个答案:

答案 0 :(得分:3)

首先声明哪个变量无关紧要:如果一个类中有一个具有相同名称的变量,那么该变量将胜过全局变量。否则,只需通过声明一个名称为其成员变量之一的全局变量,就可以在很多麻烦中获得现有代码!

当然,您的类可以使用范围解析运算符直接引用全局c

static int f() { return ::c; }

现在your program will print 3 instead of 2

答案 1 :(得分:1)

不是声明顺序而是变量范围的问题,之前在类/结构中的当前方法/函数和全局上下文中搜索使用过的变量, 例如:

#include <iostream>

const int c = 3;

struct A {
   static void print() { 
      int c = 4
      std::cout <<"Method Scope:"<< c << std::endl; // 4
      std::cout <<"Class/Struct Scope:"<< A::c << std::endl; // 2 here you can use alse ::A::c
      std::cout <<"Global Scope:"<< ::c << std::endl; // 3
   }
   static const int c = 2;
};

struct B {
   static void print() { 
      std::cout <<"Method Scope:"<< c << std::endl; // 2
      std::cout <<"Class/Struct Scope:"<< B::c << std::endl; // 2 here you can use alse ::A::c
      std::cout <<"Global Scope:"<< ::c << std::endl; // 3
   }
   static const int c = 2;
};

struct C {
   static void print() { 
      std::cout <<"Method Scope:"<< c << std::endl; // 3
      //std::cout <<"Class/Struct Scope:"<< C::c << std::endl; //is inpossible ;)
      std::cout <<"Global Scope:"<< ::c << std::endl; // 3
   }
};

int main() {
   A::print();
   B::print();
   C::print();
   return 0;
}

答案 2 :(得分:0)

想象一下,你有很长的代码使用了很多变量,你想让它们从函数所属的类调用吗?说明:

ab

课堂上的

意味着

this->a

this->b

如果您希望全局变量可见,则必须像

一样使用它 此函数内的

::a::b,通过:

static int f() { return ::c; }

从标准文档 Sec 3.3.1

  

每个名称都在程序文本的某些部分中引入,称为声明性区域,这是最大的部分   该名称有效的程序,也就是说,该名称可以用作非限定名称来引用该名称   同一实体。通常,每个特定名称仅在程序文本的某些可能不连续的部分内有效   称其范围。为了确定声明的范围,有时可以方便地参考声明的范围   声明。除非潜在范围包含另一个范围,否则声明的范围与其潜在范围相同   同名声明。在这种情况下,声明的潜在范围在内部(包含)声明中   区域被排除在外部(包含)声明区域中的声明范围之外。

这意味着潜在范围与声明的范围相同,除非发生另一个(内部)声明。如果发生,外部声明的潜在范围是删除只是内部声明保持不变,因此您的全局变量将被隐藏。