0

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?

  • Override. An overload occurs only when the methods have the same signature (but varies in the parameters provided). – Urmzd Jul 23 '21 at 21:26
  • 4
    Neither. It's shadowed. – rustyx Jul 23 '21 at 21:27
  • @Urmzd isn't it like a non-virtual method can't be overridden? – Vishal Mahavar Jul 23 '21 at 21:29
  • 1
    @rustyx can you explain a bit? some references? – Vishal Mahavar Jul 23 '21 at 21:30
  • Only virtual methods can be overridden with the `override` keyword. The term `overridden` is, itself, overloaded in the language says, because it sometimes refers to this situation: where nothing is really overriden, but if you call `fun()` through a pointer to `B` you get the subclass, and if you call `fun()` through a pointer to `A` you get the superclass's `fun()`, even if the pointer is really pointing to a superclass of an actual instance of `B`. – Sam Varshavchik Jul 23 '21 at 21:32
  • @AdrianMole I have corrected the reference. – Urmzd Jul 23 '21 at 21:39
  • @rustyx I guess we could argue all day and all night, should we choose to do so, but that is an override, plain and simple. It's *not* shadowing. – Adrian Mole Jul 23 '21 at 21:46
  • 2
    @AdrianMole - It is not an override. The person here is trying to learn C++, so it is **better** to stick to the C++ terminology. There is no override in this code. Only one method hiding another. Plain and simple. – StoryTeller - Unslander Monica Jul 23 '21 at 21:49
  • @AdrianMole I can't find a C+ reference, so I'll just remove my reference until I can. Regardless of the language, the same concepts apply. Shadowing can be boiled to a entire redefinition of some method, whereas overriding involves the redefinition of the implementation of some method. Hence, this would be considered overriding. [Reference](https://stackoverflow.com/questions/39932391/should-i-use-virtual-override-or-both-keywords). – Urmzd Jul 23 '21 at 21:52
  • @Urmzd - It's **not** an override. C++ uses its own specific terminology. You would only confuse the OP (and yourself, since `virtual` doesn't cause or prevent shadowing) by insisting on porting terminology from other domains. – StoryTeller - Unslander Monica Jul 23 '21 at 21:54
  • @StoryTeller-UnslanderMonica Meh. I guess I still need more 'updating' on *current* C++ terminology. Try as I might, I can't find an actual reference to overriding a non-virtual function. (But, in the old days, that *was* called an override.) – Adrian Mole Jul 23 '21 at 22:20
  • @AdrianMole - I learned C++03 from books written in the late nineties. The terminology hasn't changed since. It's nothing modern. – StoryTeller - Unslander Monica Jul 23 '21 at 22:57

1 Answers1

5

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".)

HTNW
  • 27,182
  • 1
  • 32
  • 60