Safely override C++ virtual functions - c++

I have a base class with a virtual function and I want to override that function in a derived class. Is there some way to make the compiler check if the function I declared in the derived class actually overrides a function in the base class? I would like to add some macro or something that ensures that I didn't accidentally declare a new function, instead of overriding the old one.
Take this example:
class parent {
public:
virtual void handle_event(int something) const {
// boring default code
}
};
class child : public parent {
public:
virtual void handle_event(int something) {
// new exciting code
}
};
int main() {
parent *p = new child();
p->handle_event(1);
}
Here parent::handle_event() is called instead of child::handle_event(), because the child's method misses the const declaration and therefore declares a new method. This could also be a typo in the function name or some minor difference in the parameters types. It can also easily happen if the interface of the base class changes and somewhere some derived class wasn't updated to reflect the change.
Is there some way to avoid this problem, can I somehow tell the compiler or some other tool to check this for me? Any helpful compiler flags (preferably for g++)? How do you avoid these problems?

Since g++ 4.7 it does understand the new C++11 override keyword:
class child : public parent {
public:
// force handle_event to override a existing function in parent
// error out if the function with the correct signature does not exist
void handle_event(int something) override;
};

Something like C#'s override keyword is not part of C++.
In gcc, -Woverloaded-virtual warns against hiding a base class virtual function with a function of the same name but a sufficiently different signature that it doesn't override it. It won't, though, protect you against failing to override a function due to mis-spelling the function name itself.

As far as I know, can't you just make it abstract?
class parent {
public:
virtual void handle_event(int something) const = 0 {
// boring default code
}
};
I thought I read on www.parashift.com that you can actually implement an abstract method. Which makes sense to me personally, the only thing it does is force subclasses to implement it, no one said anything about it not being allowed to have an implementation itself.

In MSVC, you can use the CLR override keyword even if you're not compiling for CLR.
In g++, there's no direct way of enforcing that in all cases; other people have given good answers on how to catch signature differences using -Woverloaded-virtual. In a future version, someone might add syntax like __attribute__ ((override)) or the equivalent using the C++0x syntax.

In MSVC++ you can use keyword override
class child : public parent {
public:
virtual void handle_event(int something) <b>override</b> {
// new exciting code
}
};
override works both for native and CLR code in MSVC++.

Make the function abstract, so that derived classes have no other choice than to override it.
#Ray Your code is invalid.
class parent {
public:
virtual void handle_event(int something) const = 0 {
// boring default code
}
};
Abstract functions cannot have bodies defined inline. It must be modified to become
class parent {
public:
virtual void handle_event(int something) const = 0;
};
void parent::handle_event( int something ) { /* do w/e you want here. */ }

I would suggest a slight change in your logic. It may or may not work, depending on what you need to accomplish.
handle_event() can still do the "boring default code" but instead of being virtual, at the point where you want it to do the "new exciting code" have the base class call an abstract method (i.e. must-be-overridden) method that will be supplied by your descendant class.
EDIT: And if you later decide that some of your descendant classes do not need to provide "new exciting code" then you can change the abstract to virtual and supply an empty base class implementation of that "inserted" functionality.

Your compiler may have a warning that it can generate if a base class function becomes hidden. If it does, enable it. That will catch const clashes and differences in parameter lists. Unfortunately this won't uncover a spelling error.
For example, this is warning C4263 in Microsoft Visual C++.

C++11 override keyword when used with the function declaration inside the derived class, it forces the compiler to check that the declared function is actually overriding some base class function. Otherwise, the compiler will throw an error.
Hence you can use override specifier to ensure dynamic polymorphism (function overriding).
class derived: public base{
public:
virtual void func_name(int var_name) override {
// statement
}
};

class MyClass {
public:
MyClass() {}
virtual uint32_t someFunction(bool param = false) {
if (param) {
std::cout << "This is an example virtual function with default code" << std::endl;
}
return 1100; //just for return something
};
then you can override the function as you need
class MyClass2 : public MyClass {
public:
MyClass2();
uint32_t someFunction(bool param) override;
};
uint32_t MyClass2::someFunction(bool verbose) {
std::cout << "This is new implementation for virtual method " << std::endl;
}

Related

trouble understanding dynamic polymorphism

i'm new to c++, i'm learning dynamic polymorphism. But i'm getting really confused in the details. can anyone explain why we use virtual, override and use pure virtual functions even though we can just overload methods??
Thanks
Look at this code:
class Base
{
public:
void my_method() { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
void my_method() { std::cout << "derived" << std::endl; }
};
int main()
{
Base* object = new Derived;
object->my_method();
delete object;
return 0;
}
Implemented: http://www.cpp.sh/4z4p
The output of this is "base", despite object being constructed as Derived. Add a virtual in front of Base::my_method and this changes. Add an override to Derived::my_method and it won't compile should it not actually override.
Note that while here things are easy and clear, later on you have more complicated cases and you might think that you override while you actually don't. For example, you might change the signature of the method in the base class while forgetting to change it in the subclass, or the other way around.
Pure virtual methods are to show that something is to be implemented. The idea is that you create an interface which only determines what a set of classes is supposed being able to do but which does not do anything by itself. A pure virtual class, that is. In Java, interface is actually be a keyword on it's own.
If your base has a pure virtual method and your subclass does not implement it, your compiler will result in error, which is useful.
One thing not in your list but still somewhat useful is the keyword final with which you disallow deriving a class, essentially the opposite of an interface.
overloading functions means having the same function name with a different signature - i.e. different parameters and/or return type.
int test(int a)
void test();
here, int test(int a) is an overload of void test().
virtual only exists in the context of inheritance. it means "Hey, this function can be overriden in subclasses".
override is just a hint that you actually intend to override a virtual function.
pure virtual functions look like this:
void virtualFunction() = 0;
and means that this function is abstract (in C# and Java terms), i.e. it does not contain an implementation in this class, but is meant to be overriden in one of it's subclasses. Infact you cannot instantiate a class with a non-overriden pure virtual function.

What is the opposite of c++ `override` / `final` specifier?

In c++11 the override specifier protects from not overriding an intended virtual base function (because the signatures do not match).
The 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
abstract class B : A has private: virtual void fooHasBeenDone() = 0;
class C : B implements private: virtual void fooHasBeenDone() override { react(); }
Now class A gets a new private: virtual void fooHasBeenDone();
But the new A::foo could be something different than the original B::foo.
and a specific example
abstract class B : A has virtual void showPath() = 0; meaing a PainterPath
class C : B implements virtual void showPath() override { mPath.setVisible(); }
Now class A gets a new virtual void showPath(); meaning a file path
Now when A calls showPath(), B shows the painterPath instead of some file path.
Of 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)
The facility of specifiers like first or no_override is not there as such. Probably because it may create confusion. However, it can trivially be achieved by changing the approach.
One should add any new method in the base class with final specifier. This will help to get the compiler error for any matching signatures. Because, it will make the subsequent derived class method signatures automatically as "first" of their kind. Later the final keyword can be removed, as it was intended just for "first hand verification".
Putting & removing final keyword after the newly added base method is analogically similar to compiling binary with debug (g++ -g) option, which helps you to fix bug. In production that debug option is removed for optimization.
From your example:
class A {}; // no method, no worry
class B {
public: virtual void showPath() = 0; // ok
};
...
Now accidentally you are adding similar method in A, that results in error:
class A {
public: virtual void showPath() final; // same signature by chance
// remove the `final` specifier once the signature is negotiated
};
class B {
public: virtual void showPath() = 0; // ERROR
};
So the signatures between new A::showPath() & existing B::showPath() have to be negotiated & then carry on by removing final specifier.
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.
No, there is no specifier like first or no_override. (answer)
You should use the override specifier as often as possible.
Qt has a macro Q_DECL_OVERRIDE that expands to override, if available.
If not available, at least mark each overriding function with a comment.
If you do that, there are compiler flags that warn about a missing override:
"Clang now has -Winconsistent-missing-override, and newer GCCs have -Wsuggest-override."
I don't know of a VS2012 flag for this. Feel free to edit.
You can mimic the desired behavior by adding a 'secret' that the base class cannot know. (answer)
This is helpful in very specific use cases, but generally breaks the concept of virtuality (see comments to the other answers).
If you don't own the base class and have a conflict (e.g. compiler warning), you will need to rename your virtual function in all derived classes.
If you own the base class, you can temporarily add a final to any new virtual function. (answer)
After the code compiles without errors, you know that no function of that name and signature exists in any derived class, and you can remove the 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.
No there is not.
Adding a virtual function to a base class that has the same signature as a virtual function in a child class cannot break any existing functionality unless adding that virtual function turns the base class into a polymorphic type. So in the norm, it's benign, and a purest would argue, adding language features to guard against this would be rather pointless.
(Of course you could mark your new function final just to check that a child class function isn't going to clobber it.)
Your only option is to resort to code analysis tools.
(Note that VS2012 does not implement, or even claim to implement, the C++11 standard, although it does have some of it.)
C++ doesn't seem to provide such means out of the box. But you can mimic it like follows:
template<class Base>
class Derived : public Base
{
private:
struct DontOverride {};
public:
// This function will never override a function from Base
void foo(DontOverride dummy = DontOverride())
{
}
};
If you intend to introduce a new virtual function, then do it like below:
template<class Base>
class Derived : public Base
{
protected:
struct NewVirtualFunction {};
public:
// This function will never override a function from Base
// but can be overriden by subclasses of Derived
virtual void foo(NewVirtualFunction dummy = NewVirtualFunction())
{
}
};

C++ Programm calls superclass method instead of subclass method in factory pattern

I'd like to build a factory for my Source-Plugins like that:
class PluginFactory {
public:
PluginFactory(){};
virtual ~PluginFactory(){};
static MySource* getSourceById(int id, ParameterList& pList){
switch (id){
case 1:
return new StringSource(pList);
default:
std::cout << "Unknown PluginId!" << std::endl;
return nullptr;
}
}
};
MySource cannot be abstract like usual in the pattern because it will later be used in a template class.
When I call a method of the returned MySource* I get the method of the superclass MySource instead of the overridden method of the subclass StringSource.
Any ideas how to fix this?
EDIT:
I declared the superclass method as vritual:
MySource{
...
virtual std::streamsize read(char* s, std::streamsize n){
...
}
};
I added the override command to the subclasses' read-Method:
class StringSource: public MySource {
...
std::streamsize read(char* s, std::streamsize n) override
{
...
}
};
But it still uses the superclass method. There has to be another reason...
Btw. I put the Source-Class into a boost::iostream::filtering_istream like this:
MySource* source = PluginFactory::getSourceById(1, pluginList[0].second);
boost::iostreams::filtering_istream in;
in.push(*source);
So I don't call the read-method myself.
The problem is this:
in.push(*source);
According to the documentation, this will copy the argument. Since your base class is copyable and not abstract, you encounter the slicing problem where only the base sub-object is copied.
You should be able to fix it by passing a reference wrapper instead:
in.push(std::ref(*source));
I would suggest that you make the base class abstract (or at the very least uncopyable), to prevent the possiblity of slicing. I don't understand your reason for not making it abstract; but whatever requires it to be concrete sounds scary and error-prone.
UPDATE: Since you made it concrete just so you could pass it to this function, you should make it abstract again, and pass a reference wrapper instead.
When I call a method of the returned MySource* i get the method of the superclass MySource instead of the overridden method of the subclass StringSource.
I'm not sure this will work (without seeing any relevant code), but it sounds like you need to declare your superclass method (the one you call) as virtual, so that the compiler knows to run the overridden version (in this case, of StringSource), rather than the superclass version.
Hope this helps!
The method in MySource that you call must be virtual otherwise, the one in the derived class doesn't override but, instead, hides it. For instance,
class Base {
public:
void foo() const { std::cout << "Base::foo()\n"; }
virtual void bar() const { std::cout << "Base::bar()\n"; }
};
class Derived : public Base {
public:
void foo() const { std::cout << "Derived::foo()\n"; } // hides Base::foo
void bar() const { std::cout << "Derived::bar()\n"; } // overrides Base::bar
};
Derived d;
Base& b = d;
d.foo(); // outputs Derived::foo()
b.foo(); // outputs Base::foo()
b.bar(); // outputs Derived::bar()
If you're using C++11, I would advise to use the override keyword in the declaration of Derived::bar():
void bar() const override { std::cout << "Derived::bar()"; }
More precisely, you should use override in the declaration of all derived methods that are meant to override the one in the base class. If you make a mistake and the method in the derived class doesn't override any method in the base, then the compiler will raise an error.
Herb Sutter explains the issues here.
Update: After the OP's addition of more information.
Another possible reason for the issue is as follows. If the base class is copied (e.g. when it's passed to a function by value), then the copy looses information on the dynamic type. For instance, reconsider the example above and these functions:
void call_bar_pass_by_value(Base x) {
x.bar();
}
void call_bar_pass_by_reference(const Base& x) {
x.bar();
}
Then, calling them with b gives:
call_bar_pass_by_value(b); // outputs Base::bar()
call_bar_pass_by_reference(b); // outputs Derived::bar()
I'm not familiar with Boost.Iostreams but looking at the reference documentation of filtering_stream::push() here we can see that this function does take its argument by reference. Hence, the problem that I just described doesn't happen here. However, this function might call another one which call another one ... and one of them might make take the argument by value (or make a copy of it).
The OP states that "MySource cannot be abstract like usual in the pattern because it will later be used in a template class". This suggests that an attempt to copy the object is made.
I don't know what to advise now but just to test my theory above (it doesn't solve the issue) I would temporarily make MySource's copy constructor protected to see whether Boost.Iostreams tries to copy MySource. If so, then the code will fail to compile.

Getting OOP right

Ok, this is my problem. I have the following classes:
class Job {
bool isComplete() {}
void setComplete() {}
//other functions
};
class SongJob: public Job {
vector<Job> v;
string getArtist() {}
void setArtist() {}
void addTrack() {}
string getTrack() {}
// other functions
};
// This were already implemeted
Now I want to implement a VideoJob and derived it from Job. But here is my problem. I also have the following function witch it was set to work only with SongJob:
void process(SongJob s)
{
// not the real functions
s.setArtist();
..............
s.getArtist();
.............
s.getArtist();
...............
s.setArtist()
}
Here I just want it to show that the function uses only derived object methods. So if I have another object derived from Job, I will need to change the parameter to Job, but then the compiler would not know about thoose functions and I dont what to test for everyone what kind of object it is and then cast it so I can call the correct function.
So it is okay to put all the functions in the base class, because then I will have no problem, but I don't know if this is correct OOP, if one class deals with Songs and the other with videos, I thing good oop means to have 2 clases.
If I didn't make myself clear, please say so and I will try explaining better.
And in short words, I want to use polymorfism.
It is totally fine to put all the things that the classes SongJob and VideoJob have in common into a common base-class. However, this will cause problems once you want to add a subclass of Job that has nothing to do with artists.
There are some things to note about the code you have posted. First, your class Job is apparently not an abstract base class. This means that you can have jobs that are just jobs. Not SongJob and not VideoJob. If you want to make it clear that there can not be a simple Job, make the base-class abstract:
class Job {
virtual bool isComplete() = 0;
virtual void setComplete() = 0;
//other functions
};
Now, you cannot create instances of Job:
Job job; // compiler-error
std::vector<Job> jobs; // compiler-error
Note that the functions are now virtual, which means that subclasses can override them. The = 0 and the end means that subclasses have to provide an implementation of these functions (they are pure virtual member functions).
Secondly, your class SongJob has a member std::vector<Job>. This is almost certainly not what you want. If you add a SongJob to this vector, it will become a normal Job. This effect is called slicing. To prevent it, you'd have to make it a std::vector<Job*>.
There is much more to say here, but that would go to far. I suggest you get a good book.
In your Base class Job you could add those methods as virtual methods so that a class deriving from Job may or may not override these specific methods.
In your SongJob class you override the methods and dont override them in VideoJob
In, void process() pass a pointer to Base class Job
void process(Job *s)
It will then call the appropriate methods depending on the adress of the objec s is pointing to which will be a SongJob object.
In C++, you have to do two things to get polymorphism to work:
Access polymorphic functions by a reference (&) or pointer (*) to a base type
Define the polymorphic functions as virtual in the base type
So, change these from:
class Job {
bool isComplete() {}
void setComplete() {}
};
void process(SongJob s)
{
// ...
}
To:
class Job {
public: // You forgot this...
virtual bool isComplete() { }
virtual void setComplete() { }
};
void process(Job& s)
{
// ...
}
If you can't define all the functionality you need inside process on your base class (if all the member functions you'd want don't apply to all the derived types), then you need to turn process into a member function on Job, and make it virtual:
class Job {
public:
virtual bool isComplete() { }
virtual void setComplete() { }
virtual void process() = 0;
};
// ...
int main(int argc, char* argv[])
{
SongJob sj;
Job& jobByRef = sj;
Job* jobByPointer = new SongJob();
// These call the derived implementation of process, on SongJob
jobByRef.process();
jobByPointer->process();
delete jobByPointer;
jobByPointer = new VideoJob();
// This calls the derived implementation of process, on VideoJob
jobByPointer->process();
return 0;
}
And of course, you'll have two different implementations of process. One for each class type.
People will tell you all sorts of "is-a" vs "has-a" stuff, and all sorts of complicated things about this silly "polymorphism" thing; and they're correct.
But this is basically the point of polymorphism, in a utilitarian sense: It is so you don't have to go around checking what type each class it before calling functions on it. You can just call functions on a base type, and the right derived implementation will get called in the end.
BTW, in C++, virtual ... someFunc(...) = 0; means that the type that function is defined in cannot be instantiated, and must be implemented in a derived class. It is called a "pure virtual" function, and the class it is defined on becomes "abstract".
Your problem comes from the fact you're calling a process method on an object. You should have a method Process on the Job class and override this method in your derived classes.
use pure virtual functions:
class Job
{
virtual string getArtist() =0;
};

Issues with Partial Class Function Overrides in C++

Is there any issue with partially overriding a set of virtual functions defined by a base class?
My compiler provides the following warning:
overloaded virtual function "MyBaseClass::setValue" is only partially overridden in class "MyDerivedClass".
The classes look like this:
class MyBaseClass
{
public:
virtual void setValue(int);
virtual void setValue(SpecialType*);
}
class MyDerivedClass : public MyBaseClass
{
public:
virtual void setValue(int);
}
The easy way to get rid of this warning is to use different names for the base functions, but I wanted to know if there was any compelling reason to fix this specific warning. I do not believe this violates the C++ standard. My guess is that it's to warn a programmer that they may have forgotten to implement the behavior for all possible input types. In our case, it is intentional to exclude some of the specific types.
Would you discourage suppressing this warning altogether?
The override for setValue(int) hides setValue(SpecialType*) of the base class (see the C++ FAQ Lite), so if you try to call setValue(new SpecialType()) you will get an error.
You can avoid this by adding a using directive to the derived class that "imports" the overloads from the base class:
class MyDerivedClass : public MyBaseClass
{
public:
using MyBaseClass::setValue;
virtual void setValue(int);
};
The warning is correct, it's called "name hiding". A variable of type MyDerivedClass cannot call setValue(SpecialType*).
Now I'm going to blatantly rip off someone else's blog:
Overloading and name hiding in C++
In a phone conversation with Brad last night, he told me about a strange problem he's encountered in his new C++ job. Granted, it's probably no big deal to people with extensive C++ experience, but to those of us who live in managed code worlds, this seemed strange.
In C++, when you have a class with an overloaded method (member function, whatever you want to call it), and you then extend and override that method, you must override all of the overloaded methods.
I understand the case where you have changed a method signature in a child class, thereby invalidating the established interface. In this case, though, it seems counterintuitive, since you're not changing the interface, but selectively overriding. Which is different.
For example:
class FirstClass
{
public:
virtual void MethodA (int);
virtual void MethodA (int, int);
};
void FirstClass::MethodA (int i)
{
std::cout << "ONE!!\n";
}
void FirstClass::MethodA (int i, int j)
{
std::cout << "TWO!!\n";
}
Simple class here with two methods (or one overloaded method). You want to override the two-parameter version, so you continue with the following:
class SecondClass : public FirstClass
{
public:
void MethodA (int);
};
void SecondClass::MethodA (int i)
{
std::cout << "THREE!!\n";
}
Now, when you use an instance of SecondClass, most Java or C# programmers might assume you can call:
int main ()
{
SecondClass a;
a.MethodA (1);
a.MethodA (1, 1);
}
However, the second call won't work, since the two-parameter MethodA is not visible. You can get a pointer and up-cast to FirstClass, but your SecondClass instance doesn't inherit the non-overridden methods directly.
It's clear that the compiler wants to warn you: you created a subclass that behaves differently when giving it an int, but you didn't change it's behavior when giving it a SpecialType*.
Although this might be the intention, it is very very possible that the changed behavior is also needed for the other overloaded virtual functions.
I wish the compiler had warned me harder, the time I ignored it! My overridden method turned out to compile and work well in my scenario, but some other scenario's went really wrong due to the overload not being overridden.
Think twice before you disable that warning!
If you want the original behavior kept, it's easy to just call the parent function:
class MyDerivedClass : public MyBaseClass {
virtual void setValue(int);
// explicit: keep original behavior for SpecialType
virtual void setValue( SpecialType* p ) { MyBaseClass::setValue(p); }
};