override
specifier protects from not overriding an intended virtual base function (because the signatures do not match).final
specifier protects from unintentionally overriding a function in a derived class.=> Is there a specifier (something like maybe first
or no_override
) that protects from overriding an unknown base function?
I'd like to get a compiler error when a virtual function was added to a base class with the same signature as an already existing virtual function in a derived class.
EDIT 4: To keep this question simple and answers relevant, here is again the
original pseudo-code
class B : A
has private: virtual void fooHasBeenDone() = 0;
class C : B
implements private: virtual void fooHasBeenDone() override { react(); }
class A
gets a new private: virtual void fooHasBeenDone();
A::foo
could be something different than the original B::foo
.and a specific example
class B : A
has virtual void showPath() = 0;
meaing a PainterPathclass C : B
implements virtual void showPath() override { mPath.setVisible(); }
class A
gets a new virtual void showPath();
meaning a file pathOf course this is wrong, and I should then rename B::showPath()
to B::showPainterPath()
and implement B::showPath() override
as well. I'd just like to get informed by the compiler.
Here is a compiling real-world example:
#include <iostream>
#define A_WITH_SHOWPATH
class A
{
#ifdef A_WITH_SHOWPATH
public:
void setPath(std::string const &filepath) {
std::cout << "File path set to '" << filepath << "'. Display it:\n";
showPath();
}
// to be called from outside, supposed to display file path
virtual void showPath() {
std::cout << "Displaying not implemented.\n";
}
#else
// has no showPath() function
#endif
};
class B : public A
{
public:
virtual void showPath() = 0; // to be called from outside
};
class C1 : public B {
public:
virtual void showPath() override {
std::cout << "C1 showing painter path as graphic\n";
}
};
class C2 : public B {
public:
virtual void showPath() override {
std::cout << "C2 showing painter path as widget\n";
}
};
int main() {
B* b1 = new C1();
B* b2 = new C2();
std::cout << "Should say 'C1 showing painter path as graphic':\n";
b1->showPath();
std::cout << "---------------------------\n";
std::cout << "Should say 'C2 showing painter path as widget':\n";
b2->showPath();
std::cout << "---------------------------\n";
#ifdef A_WITH_SHOWPATH
std::cout << "Should give compiler warning\n or say \"File path set to 'Test'. Display it:\"\n and \"Displaying not implemented.\",\n but not \"C1 showing painter path as graphic\":\n";
b1->setPath("Test");
std::cout << "# Calling setPath(\"Test\") on a B pointer now also displays the\n# PainterPath, which is not the intended behavior.\n";
std::cout << "# The setPath() function in B should be marked to never override\n# any function from the base class.\n";
std::cout << "---------------------------\n";
#endif
return 0;
}
Run it and look at the text output.
For reference, an older example with a specific use-case (PainterPath instance):
https://ideone.com/6q0cPD (link may be expired)
This answer is community wiki because it combines all other answers. Please upvote the specific answer that was helpful to you as well as this one.
first
or no_override
. (answer)override
specifier as often as possible.Q_DECL_OVERRIDE
that expands to override
, if available.override
:-Winconsistent-missing-override
, and newer GCCs have -Wsuggest-override
."final
to any new virtual function. (answer)final
again.... I think I'll start marking first virtual functions as DECL_FIRST
. Maybe in the future there will be a compiler-independent way of checking this.