【问题标题】:Priority between local variable and class attribute in case of name conflict名称冲突时局部变量和类属性之间的优先级
【发布时间】:2015-12-03 09:11:54
【问题描述】:

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

#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。 但这真的是确定性的吗? 是否总是优先考虑局部变量(或方法参数)和对象属性?

我问这个问题是因为我们在一个大型项目中重命名了一些变量,只是想确保行为没有“被低估”并且可能因平台、编译器而异......

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

【问题讨论】:

    标签: c++


    【解决方案1】:

    这是明确定义的:

    N3337 [basic.scope.hiding]/3: 在成员函数定义中,块范围内的名称声明隐藏了成员的声明 具有相同名称的类;见 3.3.7。

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

    【讨论】:

      【解决方案2】:

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

      众所周知,内部范围内的任何变量声明都会隐藏外部范围内的同名声明。

      考虑下面的代码sn-p

      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
                  } 
              }
          };
      

      【讨论】:

      • 很好的插图。谢谢!
      【解决方案3】:

      我认为答案是肯定的,函数或块中的局部变量总是会覆盖其他同名变量。如果要引用 A 的 m,请使用 this->m。

      【讨论】:

        猜你喜欢
        • 2016-07-13
        • 2014-03-26
        • 1970-01-01
        • 1970-01-01
        • 2012-05-07
        • 2013-12-11
        • 2013-07-12
        • 2013-09-12
        相关资源
        最近更新 更多