代码之家  ›  专栏  ›  技术社区  ›  Emile Cormier

在C++中,阴影变量名的范围分辨率(优先顺序)是什么?

  •  16
  • Emile Cormier  · 技术社区  · 15 年前

    在C++中,作用域分辨率(优先级顺序)是什么? shadowed 变量名?我在网上找不到一个简明的答案。

    例如:

    #include <iostream>
    
    int shadowed = 1;
    
    struct Foo
    {
        Foo() : shadowed(2) {}
    
        void bar(int shadowed = 3)
        {
            std::cout << shadowed << std::endl;
                // What does this output?
    
            {
                int shadowed = 4;
                std::cout << shadowed << std::endl;
                    // What does this output?
            }
        }
    
        int shadowed;
    };
    
    
    int main()
    {
        Foo().bar();
    }
    

    我想不出任何其他变量可能冲突的范围。如果我错过了,请告诉我。

    四个人的优先顺序是什么 shadow 变量内部 bar 成员函数?

    2 回复  |  直到 12 年前
        1
  •  31
  •   johnsyweb    12 年前

    第一个示例输出3。第二个输出4。

    一般的经验法则是查找从“最局部”到“最局部”变量进行。因此,这里的优先级是block->local->class->global。

    您还可以访问 每个 隐藏变量的大多数版本都显式地:

    // See http://ideone.com/p8Ud5n
    #include <iostream>
    
    int shadowed = 1;
    
    struct Foo
    {
        int shadowed;
        Foo() : shadowed(2) {}
        void bar(int shadowed = 3);
    };
    
    void Foo::bar(int shadowed)
    {
        std::cout << ::shadowed << std::endl; //Prints 1
        std::cout << this->shadowed << std::endl; //Prints 2
        std::cout << shadowed << std::endl; //Prints 3
        {
            int shadowed = 4;
            std::cout << ::shadowed << std::endl; //Prints 1
            std::cout << this->shadowed << std::endl; //Prints 2
            //It is not possible to print the argument version of shadowed
            //here.
            std::cout << shadowed << std::endl; //Prints 4
        }
    }
    
    int main()
    {
        Foo().bar();
    }
    
        2
  •  5
  •   Jerry Coffin    15 年前

    它应该打印出3。基本规则主要是通过文件向后追溯到编译器可能看到的最新定义(编辑:它没有超出范围),这就是它所使用的。对于类的局部变量,您遵循相同的 除了 所有类变量都被视为是在类定义的开头定义的。注意,这或多或少是类所独有的。例如,给定的代码如下:

    int i;
    
    int x() { 
        std::cout << i << '\n'; // prints 0;
        int i=1;
    }
    

    即使在那里 i 这是函数的局部定义,最新的定义出现在 cout 使用的是全局的,所以这就是 在那个表达中指。但是,如果这是在一个类中:

    int i;
    
    class X { 
        void y() { std::cout << i << "\n"; }
    
        X() : i(2) {}
    
        int i;
    };
    

    然后 咳嗽 表达式将引用 X::i 即使它的定义还没有被发现,当 y 正在分析。

    推荐文章