How to Enforce the 'Override' Keyword

How to enforce the 'override' keyword?

C++11 almost had what you want.

Originally the override keyword was part of a larger proposal (N2928) which also included the ability to enforce its usage:

class A
{
virtual void f();
};

class B [[base_check]] : public A
{
void f(); // error!
};

class C [[base_check]] : public A
{
void f [[override]] (); // OK
};

The base_check attribute would make it an error to override a virtual function without using the override keyword.

There was also a hiding attribute which says a function hides functions in the base class. If base_check is used and a function hides one from the base class without using hiding it's an error.

But most of the proposal was dropped and only the final and override features were kept, as "identifiers with special meaning" rather than attributes.

Requiring virtual function overrides to use override keyword

Looks like the GCC 5.1 release added exactly the warning I was looking for:

-Wsuggest-override

       Warn about overriding virtual functions that are not marked with the override keyword.

Compiling with -Wsuggest-override -Werror=suggest-override would then enforce that all overrides use override.

Is the 'override' keyword just a check for a overridden virtual method?

That's indeed the idea. The point is that you are explicit about what you mean, so that an otherwise silent error can be diagnosed:

struct Base
{
virtual int foo() const;
};

struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};

The above code compiles, but is not what you may have meant (note the missing const). If you said instead, virtual int foo() override, then you would get a compiler error that your function is not in fact overriding anything.

C++ Forcing Method Override In Concrete Class

I will assume you are looking for a compile-time enforcing of this condition (thank you @Chad for pointing it out)

There is no direct language-mechanism in C++ that I know of. I mean, there is not a reserved keyword to put in front of your method declaration that would achieve your desired goal.

I think that what you say is pointing to a design problem in your software. Let's say you want to force the foo() method to be reimplemented by all inherirhing classes in the following snippet

class BaseButConcrete
{
... //Common stuff
... //

virtual void foo()
{ /*implementation that you do not want to be inherited, but will be...*/ }
}

class DerivedOtherConcrete : public BaseButConcrete
{
void foo()
{ /*different implementation,
but no obligation from compiler point of view*/ }
}

I can see no good design reason why all the common stuff could not be moved in an abstract base class. From what you describe, you do not want to inherit the foo implementation in Derived, so do not inherit that part ! Thus the very classic design should do the trick :

class AbstractBase
{
... //Common stuff has moved here
... //
virtual void foo() =0;
}

class NotAnymoreBaseButStillConcrete : public AbstractBase
{
void foo()
{ /*implementation that should not be inherited,
and that will not by design*/ }
}

class DerivedOtherConcrete : public AbstractBase
{
void foo()
{ /*different implementation,
now mandatory compiler-wise for the class to be concrete*/ }
}

This way, the common stuff is still shared among all your derived classes, and you keep what you do not want to inherit (i.e. the foo implementation) separated in classes not on the same inheritance path.

Typescript: force to call super when override some method

There is no official way yet (in TS 4.5) to do so. I however opened this ticket with the following workaround:

class BaseComponent {
private static callSuperFoo = Symbol('Calling super.foo is mandatory');

foo() {
return BaseComponent.callSuperFoo;
}
}

class ExtendedComponent extends BaseComponent {
foo() {
// Will fail to compile without this line
return super.foo();
}
}

Explanation:
The super class is having a private static symbol callSuperFoo. Meaning

  • The Symbol is always unique, i.e. by design you cannot create another Symbol with the same signature.
  • It is static and therefore bound to the class
  • It is private, meaning, there is no way for sub classes to directly access this symbol.
  • The super method foo returns the the symbol meaning it's return type is inferred to typeof<BaseComponent.callSuperFoo>
  • The sub method foo (overriding method) must have the same signature as it's parent, it must therefore return the private super class symbol. But the only way to access and return this symbol is going threw the super.foo() method. Remember, callSuperFoois private, meaning you cannot even force casting a variable to typeof<BaseComponent.callSuperFoo>.

With this workaround, there is no way to override foo properly without calling the super.foo method.

To summarize: the sub method must return the same unique value as it's parent one, and as only it's parent is returning it: the sub method must call it's parent.

Note: This works when foo is not returning anything i.e. is void, it would be more complicated if this was not the case (I did not dug this case btw).

[EDIT]
As @Olivier Clément found a flaw, here is an even stricter typing

How to prevent a method from being overridden in derived class?

If you make the method non-virtual, derived classes cannot override the method. However, in C++03 a class cannot override a method from a base class, and also prevent further derived classes from overriding the same method. Once the method is virtual, it stays virtual.



Related Topics



Leave a reply



Submit