Andry Andry - 3 months ago 17
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 {
protected:
virtual void doSome(BaseContext* context);
};


And a derived class:

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


Since
DerivedContext
derives from
BaseContext
, it might seems that I am overriding
doSome
. 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?


Answer

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

and

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.

LIVE

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.

Comments