16

在 C++ 中,阴影变量名称的范围解析(“优先顺序”)是什么?我似乎无法在网上找到一个简洁的答案。

例如:

#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

4

2 回答 2

31

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

一般的经验法则是查找从“最局部”到“最不局部”变量。因此,这里的优先级是块 -> 本地 -> 类 -> 全局。

您还可以显式访问每个大多数版本的阴影变量:

// 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();
}
于 2010-05-10T17:31:48.063 回答
5

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

int i;

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

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

int i;

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

    X() : i(2) {}

    int i;
};

然后,即使在解析时还没有看到它的定义,cout表达式也会引用。X::iy

于 2010-05-10T17:43:13.340 回答