当前位置:  开发笔记 > 编程语言 > 正文

C++重载决议

如何解决《C++重载决议》经验,为你挑选了4个好方法。

鉴于以下示例,为什么我必须明确使用该语句b->A::DoSomething()而不仅仅是b->DoSomething()

编译器的重载决议不应该弄清楚我在谈论哪种方法?

我正在使用Microsoft VS 2005.(注意:在这种情况下使用虚拟无效.)

class A
{
  public:
    int DoSomething() {return 0;};
};

class B : public A
{
  public:
    int DoSomething(int x) {return 1;};
};

int main()
{
  B* b = new B();
  b->A::DoSomething();    //Why this?
  //b->DoSomething();    //Why not this? (Gives compiler error.)
  delete b;
  return 0;
}

Konrad Rudol.. 41

两个"重载"不在同一范围内.默认情况下,编译器仅在找到名称匹配项之前才考虑可能的最小名称范围.参数匹配完成之后.在您的情况下,这意味着编译器看到B::DoSomething.然后它尝试匹配参数列表,该列表失败.

一种解决方案是将过载从A进入B范围拉下来:

class B : public A {
public:
    using A::DoSomething;
    // …
}

@Chubsdad:这就是我把这个词放在引号中的原因.一旦该方法被拉入相同的范围,它就会变得过载. (4认同)


Pieter.. 14

重载分辨率是C++中最丑陋的部分之一

基本上,编译器在B的范围内找到名称匹配"DoSomething(int)",看到参数不匹配,并且因错误而停止.

可以通过使用B类中的A :: DoSomething来克服它

class A  
{  
  public:  
    int DoSomething() {return 0;}
};  

class B : public A  
{  
  public:  
    using A::DoSomething;
    int DoSomething(int x) {return 1;} 
};   


int main(int argc, char** argv)
{
  B* b = new B();  
  // b->A::DoSomething();    // still works, but...
  b->DoSomething();    // works now too
  delete b;  
  return 0;
}


Lehane.. 5

不,这种行为是存在的,以确保您不会被错误地从远程基类继承.

要绕过它,您需要通过在B类中放置一个使用A :: DoSomething来告诉编译器您要调用哪个方法.

有关此行为的快速简单概述,请参阅此文章.



1> Konrad Rudol..:

两个"重载"不在同一范围内.默认情况下,编译器仅在找到名称匹配项之前才考虑可能的最小名称范围.参数匹配完成之后.在您的情况下,这意味着编译器看到B::DoSomething.然后它尝试匹配参数列表,该列表失败.

一种解决方案是将过载从A进入B范围拉下来:

class B : public A {
public:
    using A::DoSomething;
    // …
}


@Chubsdad:这就是我把这个词放在引号中的原因.一旦该方法被拉入相同的范围,它就会变得过载.

2> Pieter..:

重载分辨率是C++中最丑陋的部分之一

基本上,编译器在B的范围内找到名称匹配"DoSomething(int)",看到参数不匹配,并且因错误而停止.

可以通过使用B类中的A :: DoSomething来克服它

class A  
{  
  public:  
    int DoSomething() {return 0;}
};  

class B : public A  
{  
  public:  
    using A::DoSomething;
    int DoSomething(int x) {return 1;} 
};   


int main(int argc, char** argv)
{
  B* b = new B();  
  // b->A::DoSomething();    // still works, but...
  b->DoSomething();    // works now too
  delete b;  
  return 0;
}



3> Lehane..:

不,这种行为是存在的,以确保您不会被错误地从远程基类继承.

要绕过它,您需要通过在B类中放置一个使用A :: DoSomething来告诉编译器您要调用哪个方法.

有关此行为的快速简单概述,请参阅此文章.



4> James Curran..:

派生类中方法的存在会隐藏基类中具有相同名称(无论参数)的所有方法.这样做是为了避免这样的问题:

class A {} ;
class B :public A
{
    void DoSomething(long) {...}
}

B b;
b.DoSomething(1);     // calls B::DoSomething((long)1));

比以后有人改变了A类:

class A
{
    void DoSomething(int ) {...}
}

现在突然:

B b;
b.DoSomething(1);     // calls A::DoSomething(1);

换句话说,如果它不能像这样工作,那么你不能控制的类(A)中的无关变化可能会默默地影响代码的工作方式.

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有