2017-10-13 84 views
0

我通过加速C++工作我的方式,现在,我遇到的有关范围和代码块对我而言缺乏基本的了解。为什么我可以在较小范围内重新定义一个常量?

有一个锻炼章1月底想要你来决定这些代码是否会运行:

#include <iostream> 
#include <string> 

int main() 
{ 
    { 
     const std::string s = "a string"; 
     std::cout << s << std::endl; 
     { 
      const std::string s = "another string"; 
      std::cout << s << std::endl; 
     } 
    } 
    return 0; 
} 

我肯定不会,但它确实。我的业余爱好编程经验是,块中声明的变量可用于包含在其中的其他块,但不包括其外部的块。

而且必须至少为一半,因为删除s的第二个声明会输出“一个字符串”两次,给我的印象是第二个块中声明的s也存在于第三个块中。

我还试图完全移除所述第三块的大括号,导致编译错误我预期在首位。但是,与第三块范围内已经存在的常量声明有什么不同呢?如果在较小的范围内没有第二个声明,那么常量的声明是否只能传递到较小的范围?

我通过这本书直到这一点的一切又理了一遍,看看是否我错过了什么,但我不能找到变量和常量声明是如何被大括号影响的任何信息。

+0

尝试在前两个'}'之间添加另一个'std :: cout << s << std :: endl;' – Caleth

+1

第二个's'是一个新的变量,它会影响外部作用域中的一个。它也可以有不同的类型。 – teivaz

+3

寻找的关键词是:_shadowing_。嵌套作用域中的's'会隐藏上部作用域中的一个。 –

回答

2

这并不仅仅适用于常量不过,这并不重要。

但是,它与声明第三块范围内已存在的常量有什么不同?

您正在引入另一个范围,其中变量s尚未定义,因此定义一个范围是完全合法的。如果你删除一个,你会得到一个重新定义的错误,因为你已经在同一范围内的s

如果在较小的范围内没有第二个声明,那么常量的声明是否只能传递到较小的范围?

不是。你的第二个s阴影第一个。从技术上讲,它们都存在,但你无法访问第一个。有时你在范围解析运算符的帮助下做,但在你的情况下,不。

// global scope 
int a; 
void f() { 
    int a = 0; 
    a = 4; // local 'a'. 
    ::a = 4; // global 'a'. 
} 

我找不到变量和常量声明是如何被大括号影响的任何信息。

花括号一般会引入一个新的范围(虽然有一些例外)。只要具有给定名称的变量未在当前范围中定义,您可以定义它。如果在其范围外有一个具有相同名称的变量,则无关紧要,但编译器可能会提醒您。

+0

谢谢,这有帮助。有点奇怪,本书希望你知道这一点,但。刚刚检查了索引,在整本书中没有提到“阴影”或“阴影”。它也没有真正意义上的主题,因为这应该检查你对常量的知识。也许这是一个拼写错误,而's =“另一个字符串”是为了在第三个块中。 – mwyah

3

Java和C++是为数不多的人之一。 C#不允许这样做。 它被称为可变阴影。如果你在一个较小的内部块中声明一个与外部块变量相同名称的变量,那么你将得到名称掩码。 所以它没关系,你有一个const变量,因为内部变量是一个完全不同的变量。

相关问题