在具有相同名称的全局函数中选择的类静态成员函数?

时间:2011-04-29 08:57:41

标签: c++ static-methods

Doubt originated from here


int g() {
   cout << "In function g()" << endl;
   return 0;
}

class X {
public:
  static int g() {
     cout << "In static member function X::g()" << endl;
     return 1;
  }
};

class Y: public X {
   public:
  static int i;
};

int Y::i = g();   

最初我认为,因为符号解析从最内部范围到最外部范围发生,这就是为什么要调用x :: g()。但是后来我仔细注意了代码

int Y::i = g();

我们如何在没有名称范围的情况下访问X :: g()?
这个语句所在的范围应该是全局的,而不是Y ::或X ::,所以符号解析应该给出函数g()的全局版本?

2 个答案:

答案 0 :(得分:11)

注意:我认为我之前的回答是错误的。它不是Koenig Lookup,而是依赖于参数的名称查找(ADL)。所以我删除了我(之前)的答案,因为我找到了标准中回答你问题的相关部分。

您的代码直接来自C ++ 03标准的第9.4.2节。

  

可以参考静态成员   直接在其类或范围内   在派生类的范围内   (第10条)从其班级;在这   case,引用静态成员   好像是一个合格的id表达式   使用,使用嵌套名称说明符   命名类的qualified-id   静态成员的范围   引用。

然后给出了这个例子(你在问题中提到过)

[Example:

    int g();
    struct X {
        static int g();
    };
    struct Y : X {
        static int i;
    };
    int Y::i = g(); // equivalent to Y::g();

—end example]

然后在§9.4/ 3中说明

  

如果使用了nonqualified-id(5.1)   静态成员的定义   在会员的声明者身份之后,   和名称查找(3.4.1)发现   unqualified-id指静态   成员,枚举器或嵌套类型   成员的类(或基类)   成员的班级),   unqualified-id转换为a   qualified-id表达式中的   nested-name-specifier为该类命名   成员所在的范围   参考

由于在静态成员的定义中发生,这意味着{strong}初始化中仅调用Y::g(),不在作业

//definition-cum-initialization
int Y::i = g(); // equivalent to Y::g();
int main()
{
   //assignment 
   Y::i = g(); // does not equivalent to Y::g(); it calls global g()
}

请参阅此处的输出:http://www.ideone.com/6KDMI

让我们考虑另一个例子:

struct B{};

B f();

namespace NS 
{
   struct A { static B b;};
   B f();
}

//Definition cum Initialization
B NS::A::b = f();  //calls NS::f()
B b = f();         //calls global f()

int main() 
{
   //Assignment
   NS::A::b = f(); //calls global f()
   b = f();        //calls global f()
}

请参阅此处的完整演示:http://www.ideone.com/53hoW

答案 1 :(得分:9)

这是因为您使用int Y::i =...,请注意Y::。这就是原因,它实际上在g()内寻找YX::g(),因为Y派生X


添加:例如,如果您将int i = g();放在int Y::i = g();之后,则会产生以下结果:

In static member function X::g()
In function g()

编辑:完全 - 依赖于参数的名称查找。我不记得在开始时这是怎么调用的。感谢Nawaz的回答(:

EDIT2 :好的,Nawaz找到了正确的解释,它在标准中并且似乎不是“依赖于参数的名称查找”。但逻辑仍然绝对相同。

相关问题