Abe*_*Abe 36 c++ overloading resolution function
鉴于以下示例,为什么我必须明确使用该语句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;
}
Run Code Online (Sandbox Code Playgroud)
Kon*_*lph 41
两个"重载"不在同一范围内.默认情况下,编译器仅在找到名称匹配项之前才考虑可能的最小名称范围.参数匹配完成之后.在您的情况下,这意味着编译器看到B::DoSomething
.然后它尝试匹配参数列表,该列表失败.
一种解决方案是将过载从A
进入B
范围拉下来:
class B : public A {
public:
using A::DoSomething;
// …
}
Run Code Online (Sandbox Code Playgroud)
Pie*_*ter 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;
}
Run Code Online (Sandbox Code Playgroud)
派生类中方法的存在会隐藏基类中具有相同名称(无论参数)的所有方法.这样做是为了避免这样的问题:
class A {} ;
class B :public A
{
void DoSomething(long) {...}
}
B b;
b.DoSomething(1); // calls B::DoSomething((long)1));
Run Code Online (Sandbox Code Playgroud)
比以后有人改变了A类:
class A
{
void DoSomething(int ) {...}
}
Run Code Online (Sandbox Code Playgroud)
现在突然:
B b;
b.DoSomething(1); // calls A::DoSomething(1);
Run Code Online (Sandbox Code Playgroud)
换句话说,如果它不能像这样工作,那么你不能控制的类(A)中的无关变化可能会默默地影响代码的工作方式.