名称冲突时局部变量和类属性之间的优先级

时间:2015-12-03 09:11:55

标签: c++

假设你有这个非常愚蠢的代码(它只是为了让你轻松提出即将到来的问题):

#include <iostream>

class A
{
public:
    A() : m(0) {}

    void showM1( int m )
    {
        std::cout << m << std::endl;
    }

    void showM2()
    {   
        int m = 5;
        std::cout << m << std::endl;
    }

    int m;
};

int main()
{
    A a;
    a.showM1( 5 );
    a.showM2();
}

When I tested,不要太惊讶,它显示5和5。 但这真的是确定性的吗? 优先级是否总是赋予局部变量(或方法参数)和对象属性?

我问,因为我们在一个巨大的项目中重命名了一些变量,并且只是想确保这个行为不是&#34;不确定&#34;并且可能因平台,编译器而异......

PS:我知道这是不好的实践,并且发现主题提到最好的方法是避免名称冲突(如this one)....

3 个答案:

答案 0 :(得分:6)

这是明确界定的:

  

N3337 [basic.scope.hiding]/3:在成员函数定义中,块作用域中名称的声明隐藏成员的声明   同名的班级;见3.3.7。

m在块范围内的成员函数定义中,因此它隐藏了类成员m

答案 1 :(得分:1)

类成员函数局部变量实际上是在类作用域的内部作用域中声明的。

众所周知,内部作用域中的任何变量声明都会在外部作用域中隐藏一个具有相同名称的声明。

请考虑以下代码段

int x = 1;

namepsace N1
{
    int x = 2;

    struct A
    {
        int x = 3;
    };

    struct B : A
    {
        int x = 4;
        void f( int x = 5 ) { { int x = 6; } }
    };
}

您可以通过以下方式想象范围

int x = 1; // global namespace
{
    int x = 2; // namepsace N1
    {
        int x = 3;  // struct A scope
        {
            int x = 4; // struct B scope
            {
                int x = 5; // the funcion f's outer-most scope
                {
                    int x = 6; // function f's inner scope
                    std::cout << x << std::endl;    // outputs 6
                    // here can not output the function parameter x = 5
                    std::cout << B::x << std::endl; // outputs 4
                    std::cout << A::x << std::endl; // outputs 3
                    std::cout << N::x << std::endl; // outputs 2
                    std::cout << ::x << std::endl;  // outputs 1
                }  
            }
        }
    }
}

要对此进行测试,您可以将上面显示的所有输出语句放在成员函数定义

    struct B : A
    {
        int x = 4;
        void f( int x = 5 ) 
        { 
            { 
                int x = 6; 

                std::cout << x << std::endl;    // outputs 6
                // here can not output the function parameter x = 5
                std::cout << B::x << std::endl; // outputs 4
                std::cout << A::x << std::endl; // outputs 3
                std::cout << N::x << std::endl; // outputs 2
                std::cout << ::x << std::endl;  // outputs 1
            } 
        }
    };

答案 2 :(得分:0)

我认为答案是肯定的,函数或块中的局部变量将始终覆盖其他具有相同名称的变量。如果要引用m的A,请使用this-&gt; m。