Vishal Mahavar
Vishal Mahavar

Reputation: 43

Is the method overridden or overloaded?

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

Answers (1)

HTNW
HTNW

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

Related Questions