Reputation: 43
We have two classes.
class A{
public:
void fun(){
cout<<"Parent\n";
}
};
class B:public A{
public:
void fun(){
cout<<"Child\n";
}
};
I am trying to figure out if the function fun()
will be considered overloaded
or overridden
.
I tried using the override
keyword and it says that the method is not overridden. But I wonder if the override
keyword will only work if the function in the parent class is written as virtual
and if the function can be considered as overridden in the case mentioned above.
Also, I want to know if overriding a method always means late-binding/runtime-polymorphism?
Upvotes: 0
Views: 137
Reputation: 29193
B::fun
neither overloads nor overrides A::fun
. It hides it. It's not an override because you can still get the A::fun
behavior on a B
by treating it as an A
B x;
A &y = x;
y.fun(); // outputs Parent
When you try to access the fun
method through the A
interface, you get the Parent
behavior. Were A::fun
declared virtual
, then B::fun
would override it and the fun
method accessed through the A
interface would output Child
.
The difference between overloading and hiding is not clear here because the argument lists are the same, but consider the hierarchy
struct A {
void foo(int i) { std::cout << i << "\n"; }
};
struct B : A {
void foo(std::string const &s) { std::cout << std::quoted(s) << "\n"; }
};
If B::foo
just overloaded A::foo
then this would work
B x;
x.foo(5);
But it does not. Note that x
still has the foo(int)
method.
A &y = x;
y.foo(5); // works
You just can't get to it through the B
interface. This is because overload resolution is only done among the set of members declared in the same class. If a class doesn't declare a member of the name, then it goes to the base classes, but if the class does declare the name and none of them match, the resolution just fails right there. (I.e. removing B::foo
would make x.foo(5)
work.)
You can request overloading instead of hiding from the language with a using
directive, but again overriding is impossible unless A::fun
is virtual
(and B::fun
would need to have the same argument list as A::fun
).
struct B : A {
using A::foo;
void foo(std::string const &s) { std::cout << std::quoted(s) << "\n"; }
};
(P.S. Regarding the comments, the technical term in C++ is indeed hiding. Shadowing may be the word used for this behavior in other languages, but the C++ standard uses "hiding".)
Upvotes: 5