Andry Andry - 1 month ago 5x
C++ Question

C++: override or overload?

I have two classes representing contexts for some methods.

class BaseContext {};
class DerivedContext : public BaseContext {};

I have a base class:

class MyBase {
virtual void doSome(BaseContext* context);

And a derived class:

class MyDerived : public MyBase {
virtual void doSome(DerivedContext* context) override; // Overriding
virtual void doSome(DerivedContext* context); // Overloading?

derives from
, it might seems that I am overriding
. But it might also be an overloading...

  1. Which one is correct? Am I overriding or overloading here?

  2. Thus, if I type
    (MyBase* my = new MyDerived())->doSome(new DerivedContext())
    , what should I get?


This is neither overriding nor overloading. Since the parameter's type is different, MyDerived::doSome is just hiding MyBase::doSome.

1.1. Since DerivedContext derives from BaseContext, it might seems that I am overriding doSome.

No, it's not overriding. Here're the preconditions of overriding listed in the standard. $10.3/2 Virtual functions [class.virtual]:

(emphasis mine)

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides110 Base::vf.

In fact with keyword override a compile error will be generated for this case.

error: 'doSome' marked 'override' but does not override any member functions


1.2. But it might also be an overloading...

You can't overload functions across scopes according to the rule of unqualified name lookup (unless using using-declaration to introduce names into the same scope).

  1. Thus, if I type (MyBase* my = new MyDerived())->doSome(new DerivedContext()), what should I get?

MyBase::doSome() will be invoked since you call it on a MyBase*. This is not overriding, so no dynamic dispatching happens here.


Note the argument DerivedContext* will be implicitly converted to BaseContext* and then passed to the function. BTW (MyBase* my = new MyDerived())->... is not valid syntax.