Say i have this part of code:
#include<iostream>
using namespace std;
class A {
public:
virtual int f(const A& other) const { return 1; }
};
class B : public A {
public:
int f(const A& other) const { return 2; }
virtual int f(const B& other) const { return 3; }
};
void go(const A& a, const A& a1, const B& b) {
cout << a1.f(a) << endl; //Prints 2
cout << a1.f(a1) << endl; //Prints 2
cout << a1.f(b) << endl; //Prints 2
}
int main() {
go(A(), B(), B());
system("pause");
return 0;
}
I can understand why the first two will print 2. But I cannot understand why the last print is also 2. Why doesn't it prefers the overloaded function in B
?
I already looked at this and this but I couldn't manage to understand from these.
The confusion comes in that your:
int f(const A& other) const { return 2; }
line is actually virtual also and is overriding your line:
virtual int f(const A& other) const { return 1; }
Meanwhile, the line:
virtual int f(const B& other) const { return 3; }
ends up being completely ignored because everything matches to the "return 1" line, then follows polymorphically up the chain to the "return 2" line. As the other poster said, the
const B
portion means it won't match the polymorphic method call.As an aside: If you're getting a 2 on the first line, I'm suspicious of undesired stack behavior. I'd expect a 1. Perhaps try allocating like this:
It's easy, really. You're calling
f
on an object with static typeA
.A
has only onef
, so there's only one entry in thevtable
for that function. Overload resolution takes place compile-time. The overload will only be resolved if you call it on an object whose static type isB
int B::f(const B& other) const
doesn't overrideint A::f(const A& other) const
because the parameter type is not the same. Then it won't be called via callingf()
on reference of the base classA
.If you use override specifier (since C++11) compiler will generate the error.
Such as Clang:
If you add an overload for it in the base class, you might get what you want. Note that a forward declaration of class
B
will be needed.LIVE