简体   繁体   English

为什么我可以在较小的范围内重新定义const?

[英]Why can I redefine a const in a smaller scope?

I'm working my way through Accelerated C++ right now, and I've encountered a fundamental lack of understanding regarding scope and code blocks on my part. 我现在正在通过Accelerated C ++进行工作,而我却遇到了对范围和代码块的根本性了解。

There is an exercise at the end of chapter 1 that wants you to decide whether this code is will run: 第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;
}

I was sure it wouldn't, but it does. 我确定不会,但是可以。 My hobby programming experience was that variables declared in a block are available to other blocks contained within it, but not those outside of it. 我的业余编程经验是,在块中声明的变量可用于其中包含的其他块,但不能用于其中的其他块。

And that must be at least half-true, since removing the second declaration of s will output "a string" twice, giving me the impression that s as declared in the second block is also present in the third block. 而且这至少必须是一半,因为删除s的第二个声明将输出两次“字符串”,给我的印象是在第二个块中声明的s也出现在第三个块中。

I also tried removing the braces of the third block entirely, resulting in the compilation error I expected in the first place. 我还尝试完全删除了第三个块的花括号,从而导致了我最初期望的编译错误。 But how is that different from declaring a constant that already exists in the scope of the third block? 但是,与声明第三个块范围内已经存在的常量有何不同? Does the declaration of a constant only carry over to a smaller scope if there is no second declaration in that smaller scope? 如果在该较小范围内没有第二个声明,则常量声明仅会延续到较小范围吗?

I've gone through everything in the book up until this point again to see if I missed something, but I can't find any information on how variable and const declarations are affected by curly braces. 我已经遍历了本书中的所有内容,直到现在再看是否遗漏了一些东西,但是我找不到有关花括号如何影响变量和const声明的任何信息。

Java and C++ are one of the few that allows this. Java和C ++是允许这样做的少数几个。 C# does not allow this. C#不允许这样做。 It is called Variable Shadowing. 这称为可变阴影。 If you declare a variable with same name in a smaller inner block as outer blocks variable then you get name masking. 如果在较小的内部块中声明与外部块变量同名的变量,则会得到名称屏蔽。 So it doesnt matter that you have a const variable because the inner variable is a different variable altogether. 因此,拥有const变量并不重要,因为内部变量完全是另一个变量。

This doesn't just apply to constants though, that doesn't matter. 但是,这不仅适用于常量,也没有关系。

But how is that different from declaring a constant that already exists in the scope of the third block? 但是,与声明第三个块范围内已经存在的常量有何不同?

You are introducing another scope, where the variable s has not been defined, so it is perfectly legal to define one. 您正在引入另一个范围,其中尚未定义变量s ,因此定义一个范围是完全合法的。 If you remove one, you'll get a redefinition error, because you already have an s in the same scope. 如果你删除一个,你会得到一个重新定义的错误,因为你已经有一个s在同一范围内。

Does the declaration of a constant only carry over to a smaller scope if there is no second declaration in that smaller scope? 如果在该较小范围内没有第二个声明,则常量声明仅会延续到较小范围吗?

Not really. 并不是的。 Your second s is shadowing the first one. 您的第二个s 遮盖了第一个。 Technically, both of them exist, but you have no way of accessing the first one. 从技术上讲,它们两者都存在,但是您无法访问第一个。 Sometimes you do, with the help of the scope resolution operator, but in your case, no. 有时,您可以在范围解析运算符的帮助下执行此操作,但是在您的情况下,不需要。

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

I can't find any information on how variable and const declarations are affected by curly braces. 我找不到有关花括号如何影响变量和const声明的任何信息。

Curly braces in general introduce a new scope (although there are some exceptions). 大括号通常会引入一个新的范围(尽管有一些例外)。 As long as a variable with a given name is not defined in the current scope, you can define it. 只要在当前作用域中未定义具有给定名称的变量,就可以对其进行定义。 It doesn't matter if there is a variable with the same name in a scope outside of it, but your compiler will likely warn you about it. 外部作用域中是否有同名变量并不重要,但是编译器可能会警告您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM