为了账号安全,请及时绑定邮箱和手机立即绑定

C ++重载解析

/ 猿问

C ++重载解析

C++
繁花如伊 2019-11-14 14:19:02

给定以下示例,为什么我必须显式使用语句b->A::DoSomething()而不是b->DoSomething()?


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


我使用的是Microsoft VS2005。(注意:在这种情况下,使用虚拟无助。)


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;

}


查看完整描述

3 回答

?
MM们

这两个“过载”不在同一个范围内。默认情况下,编译器只会在名称匹配之前考虑最小的名称范围。参数匹配完成之后。在您的情况下,这意味着编译器将看到B::DoSomething。然后,它尝试匹配参数列表,但失败了。


一种解决方案是将重载从降低A到B的范围:


class B : public A {

public:

    using A::DoSomething;

    // …

}


查看完整回答
反对 回复 2019-11-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;

}


查看完整回答
反对 回复 2019-11-14
?
呼啦一阵风

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


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)中不相关的更改可能会无声地影响代码的工作方式。


查看完整回答
反对 回复 2019-11-14

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信