C++ Virtual Override Functions with Same Name

C++ virtual override functions with same name

You cannot use qualified names there. I you write void Function() { ... } you are overriding both functions. Herb Sutter shows how it can be solved.

Another option is to rename those functions, because apparently they do something different (otherwise i don't see the problem of overriding both with identical behavior).

Overloading virtual functions of the same name from different base classes. Is it possible?

No. This is not possible. It will always conflict with either of the fn().

The syntax of fn() are different,

void fn();  // in A

and in B is,

int fn();  // in B

You have to make those syntax same in A and B to let C implement the fn(). Demo.

Virtual functions with same name but different arguments and return types

There's no function taking a double in Base. And all you have is a pointer to Base. So the 2.3 is truncated to the int value 2 and Base::func(int i) is called.

Derived::func(double d) is not in play at all in this code.

It doesn't matter that func is virtual in Base, since the func in Derived does not override it (the signatures don't match). Adding the override keyword to Base::func will make that clear instantly as a compiler error.

C++ override specifier without virtual? Does override imply virtual?

The answer you're looking for is in https://en.cppreference.com/w/cpp/language/virtual

If some member function vf is declared as virtual in a class Base, and some class Derived, which is derived, directly or indirectly, from Base, has a declaration for member function with the same
name
parameter type list (but not the return type)
cv-qualifiers
ref-qualifiers
Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration) and overrides Base::vf (whether or not the word override is used in its declaration).

Can you override a pure virtual function within the same class?

I want to keep this interface in subclasses and be able to override it,

That will be already the case automatically, because you inherited it at the public access level.

for example I have a class for a Game, which cleans the screen, draw stuff and than flip the display buffer ...

...
Is there any way to do this sort of thing in C++11?

Completely independent of any c++11 particularities, just write an implementation for the abstract function declaration, and add an additional layer of indirection (aka the Template Method Pattern):

class Game : public IDraw {
public:
// Keep the interface
// This can be overridden by sub classes
void do_draw(Screen *scr) override {
OnPreDraw(scr);
OnDraw(scr);
OnPostDraw(scr);
}
protected:
virtual void OnPreDraw(Screen *scr) {
// Default implementation
scr->clear();
}
virtual void OnDraw(Screen *scr) = 0; // << Class is still abstract
virtual void OnPostDraw(Screen *scr) {
// Default implementation
scr->present();
}
};

This would allow to inject any implementation of Game at that finer grained sequence of operations, but keep default behavior from the base class implementation.

Also the base class is still abstract and effectively forces any derived class to implement OnDraw(), which is effectively the same as do_draw().

but since I need many class doing this kind of stuff it will end with plenty of names for the same concept.

No. As far your concept just involves the operations

 OnPreDraw(scr);
OnDraw(scr);
OnPostDraw(scr);

in that sequence, that won't change for the whole class inheritance hierarchy anymore in future.


To an extend:

You can also do that with Mixin pattern classes1

template<typename Derived>
class AbstractIDrawImpl : public IDraw {
void do_draw(Screen *scr) override {
static_cast<Derived*>(this)->OnPreDraw(scr);
static_cast<Derived*>(this)->OnDraw(scr);
static_cast<Derived*>(this)->OnPostDraw(scr);
}

// Expects public implementations
void OnPreDraw(Screen *scr) {
// Default implementation
scr->clear();
}
// Just no default implementation for
// void OnDraw(Screen *scr) << Class is still abstract
void OnPostDraw(Screen *scr) {
// Default implementation
scr->present();
}
};

The above mixin example can be bound to any implementation of IDraw that provides public functions for OnPreDraw() , OnDraw() and OnPostDraw():

class MyGame : public AbstractIDrawImpl<MyGame> {
public:
// IDraw interface implementation
void OnPreDraw(Screen *scr) {
// Call base class implementation
AbstractIDrawImpl<MyGame>::OnPreDraw(scr);
// E.g fill my background here
}
void OnDraw(Screen *scr) {
// For each game entity call
// IDraw::do_draw(scr);
for(auto drawableEntity : drawableEntities_) {
drawableEntity->do_draw(scr);
}
}
// Skip implementation of OnPostDraw()
private:
std::vector<std::shared_ptr<IDraw>> drawableEntities_;
};

1)

That pattern is well described with Alexei Andrescou's Policy based design paradigm and heavily used with Microsoft's ATL.

C++: Override method which has the same name as the class

Okay, here's my (slightly evil) solution...

// Create an intermediate class which actually implements the foo method:
class foo_intermediate : public base
{
public:
virtual void foo() const override;
};

// Derive from that class and forward the constructor along
class foo : public foo_intermediate
{
public:
using foo_intermediate::foo_intermediate;

private:
friend class foo_intermediate;

// Actual implementation for the foo function goes here
void foo_impl() const;
};

// In some CPP file:
void foo_intermediate::foo() const
{
// Need to access the typename foo via namespace (global here)
static_cast<const ::foo*>(this)->foo_impl();
}

Actually calling foo is a bit funny, since this can't work:

void bar()
{
foo x;
x.foo(); // <- illegal attempt to access to the foo constructor
}

You must access through an alias:

void baz()
{
foo x;
base& rx = x;
rx.foo(); // legal
}

As an alternative, you can use a typedef:

class foo_impl : public base
{
public:
virtual void foo() const override;
};

using foo = foo_impl;

This gets around the issue of calling x.foo(), since it no longer appears as a constructor access.


I made a Gist so others could play with the two solutions if they are so inclined.

Should I use virtual, override, or both keywords?

When you override a function you don't technically need to write either virtual or override.

The original base class declaration needs the keyword virtual to mark it as virtual.

In the derived class the function is virtual by way of having the ¹same type as the base class function.

However, an override can help avoid bugs by producing a compilation error when the intended override isn't technically an override. For instance, the function type isn't exactly like the base class function. Or that a maintenance of the base class changes that function's type, e.g. adding a defaulted argument.

In the same way, a virtual keyword in the derived class can make such a bug more subtle by ensuring that the function is still virtual in the further derived classes.

So the general advice is,

  • Use virtual for the base class function declaration.

    This is technically necessary.

  • Use override (only) for a derived class' override.

    This helps maintenance.

Example:

struct Base { virtual void foo() {} };
struct Derived: Base { void foo() override {} };


Notes:
¹ C++ supports covariant raw pointer and raw reference results. With covariance the type of the override isn't exactly the same. It just has a compatible type.

How to implement virtual functions with the same name in multiple inheritance

class C_a 
: public A
{
virtual void F_A() = 0;
virtual void F() { this->F_A() };
};

class C_b
: public B
{
virtual void F_B() = 0;
virtual void F() { this->F_B() };
};

class C
: public C_a
, public C_b
{
void F_A() { ... }
void F_B() { ... }
};

If I'm remembing right the ISO committee thought about this problem and discussed a change of the language. But then ... somebody found this nice way to solve this problem :-)

Your second solution is better in case your are able to change your class hierarchy. You may have a lock at http://www.gotw.ca/publications/mill18.htm for a description why it is better.

How to override base classes' virtual functions that have identical names in multiple inheritance?

I don't think what you want to do is possible in the manner you've shown in the question. From N3337, §10.3/2 [class.virtual]

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 (8.3.5), 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 overrides Base::vf. ...

D::foo matches all those criteria for B1::foo and B2::foo, hence it overrides both. And since B1::foo is final, the code is ill-formed.

One workaround is to introduce an extra level of inheritance. Define a class, say D2, that derives from B2 and overrides B2::foo. Then D can derive from B1 and D2 instead.

class D2 : public B2{
public:
virtual void foo() override { cout << __PRETTY_FUNCTION__ << '\n'; }
};

class D :public B1, public D2
{};

D d;
// d.foo(); // error - ambiguous

D2& d2 = d;
d2.foo(); // calls D2::foo
B2& b2 = d;
b2.foo(); // calls D2::foo

B1& b1 = d;
b1.foo(); // calls B1::foo

Live demo



Related Topics



Leave a reply



Submit