There is an abstract class A which has a pure virtual member function func(). A great number of derived classes are present, each one with a different implementation of func().
Imagine now that you want to add an extra task to be carried out at each call of func(), let's say a cout << "hello world"; independently from the derived class. The task is also independent from the content of func() so it could be executed before, after or even in the middle of func(), only the fact that it gets executed once each call to func() matters.
Does c++(11) allow a smart way to do this?
The best thing that comes to my mind is to write a pre-func() method in the parent class where the task is implemented and copy a call to pre-func() at the beginning of all the func() implementations in the derived classes. Anything better?
I believe you could use the Non-virtual interface idiom
You'd have the base class as follow:
class A{
public:
void myFunc();
private:
virtual void myVirtualFunc();
}
with notably the following in the .cpp :
void A::myFunc(){
//stuff
myVirtualFunc();
//stuff
}
Then each derived class can reimplement myVirtualFunc() and change its behavior. The virtual is private so you're guaranteed it won't be called anywhere but in the public non-virtual defined by the base class (guaranteeing that the code you need to run for each call will be ran), and the private visibility doesn't prevent the derived class from reimplementing it. The derived class can specify what the virtual does, not where (though as mentioned by #WhozCraig, the derived class still can reimplement the virtual function as public).
If I understand the question correctly one option available to you is to create the "pre-func()" method in the base class and have that function print "Hello World" and then call "func()". That way your derived classes all override "func()" but you invoke the API through "pre-func()" (obviously I wouldn't use the term pre-func as it no longer describes the functionality accurately)
Related
Is it good practice to make a base class constructor protected if I want to avoid instances of it? I know that I could as well have a pure virtual dummy method, but that seems odd...
Please consider the following code:
#include <iostream>
using std::cout;
using std::endl;
class A
{
protected:
A(){};
public:
virtual void foo(){cout << "A\n";};
};
class B : public A
{
public:
void foo(){cout << "B\n";}
};
int main()
{
B b;
b.foo();
A *pa = new B;
pa->foo();
// this does (and should) not compile:
//A a;
//a.foo();
return 0;
}
Is there a disadvantage or side-effect, that I don't see?
It is common practice to make base class constructors protected. When you have a pure-virtual function in your base class, this is not required, as you wouldn't be able to instantiate it.
However, defining a non-pure virtual function in a base class is not considered good practice, but heavily depends on your use case and does not harm.
There isn't any disadvantage or side-effect. With a protected constructor you just tell other developers that your class is only intended to be used as a base.
What you want to achieve is normally done via the destructor, instead of the constructors, just beacause you can steer the behavior you need with that one function instead of having to deal with it with every new constructor you write. It's a common coding style/guideline, to
make the destructor public, if you want to allow instances of the class. Often those classes are not meant to be inherited from.
make the destructor pure virtual and public, if you want to use and delete the class in a polymorphic context but don't want to allow instances of the class. In other words, for base classes that are deleted polymorphcally.
make the destructor nonvirtual and protected, if you don't want to allow instances of the class and don't want to delete its derivates polymorphically. Normally, you then don't want to use them polymorphically at all, i.e. they have no virtual functions.
Which of the latter two you chose is a design decision and cannot be answered from your question.
It does what you're asking.
However I'm not sure what you are gaining with it. Someone could just write
struct B : A {
// Just to workaround limitation imposed by A's author
};
Normally it's not that one adds nonsense pure-virtual functions to the base class... it's that there are pure virtual functions for which no meaningful implementation can be provided at the base level and that's why they end up being pure virtual.
Not being able to instantiate that class comes as a nice extra property.
Make the destructor pure virtual. Every class has a destructor, and a base class should usually have a virtual destructor, so you are not adding a useless dummy function.
Take note that a pure virtual destructor must have a function body.
class AbstractBase
{
public:
virtual ~AbstractBase() = 0;
};
inline AbstractBase::~AbstractBase() {}
If you don't wish to put the destructor body in the header file, put it in the source file and remove inline keyword.
So, based on a cursory search, I already know that calling a virtual function (pure or otherwise) from a constructor is a no go. I have restructured my code to ensure that I am not doing that. While this causes the user of my classes to add an extra function call in their code, this is really not that big of a deal. Namely, instead of calling the constructor in a loop, they now call the function which (in fact!) increases performance of the code since we don't have the housekeeping of building and destroying the object in question every time.
However, I have stumbled across something interesting...
In the abstract class I have something like this:
// in AbstractClass.h:
class AbstractClass {
public:
AbstractClass() {}
virtual int Func(); //user can override
protected:
// Func broken up, derived class must define these
virtual int Step1() = 0;
virtual int Step2() = 0;
virtual int Step3() = 0;
// in AbstractClass.cpp:
int AbstractClass::Func() {
Step1();
// Error checking goes here
Step2();
// More error checking...
// etc...
}
Basically, there is a common structure that the pure virtual functions follow most of the time, but if they don't Func() is virtual and allows the derived class to specify the order. However, each step must be implemented in derived classes.
I just wanted to be sure that there's nothing that I necessarily am doing wrong here since the Func() function calls the pure virtual ones. That is, using the base class, if you call StepX(), bad things will happen. However, the class is utilized by creating a derived object and then calling Func() (e.g. MyDerivedObject.Func();) on that derived object, which should have all the pure virtual functions overloaded properly.
Is there anything that I'm missing or doing incorrectly by following this method? Thanks for the help!
Func is calling the virtual ones, not the pure virtual ones. You would have to qualify the calls with a scope operator, i.e. AbstractClass::Step1() to call THAT (virtual pure) function. Since you are not, you will always get an implementation by a derived class.
A virtual function in a base class makes the derived classes able to override it. But it seems things stop there.
But if the base class virtual function is pure, that forces the derived classes to implement the function.
As a side comment you can make the Step1, Step2, Step3 methods private so that you'll be prevented by the compiler from directly calling them.
I'm now learning C++, the OO side, and I see this all the time:
class SomeClass{
virtual void aMethod()=0;
}
class AnotherClass{
void anotherMethod(){/*Empty*/}
}
class SomeClassSon : public SomeClass{
void aMethod(){/*Also Empty*/}
}
what is the difference between the 3 methods? The virtual equals zero, the empty one, and the virtual, since it is inherited, empty one.
Why can't I just make the SomeClassSon method like the father, virtual void equals zero?
For your
class SomeClass{
virtual void aMethod()=0;
}
the presence of a pure virtual method makes your class abstract. Once you have one such pure virtual method, =0, in your class, you cannot instantiate the class. What is more, any derived class must implement the pure virtual aMethod(), or it becomes an abstract class as well.
In your derived class, you overwrite the pure virtual method from above, and this makes the derived class non abstract. You can instantiate this derived class.
But, in derived class, method's body is empty, right? That's why your question makes sense: why not make the class pure virtual as well. Well, your class may entail other methods. If so, SomeClass cannot be instantiated (there is a pure virtual method), whereas child class SomeClassSon can be.
Same applies to your AnotherClass, which can be instantiated, contrary to SomeClass.
The difference is that virtual void aMethod() = 0 is a pure virtual function, meaning that:
SomeClass becomes an abstract base class,
meaning it cannot be instantiated.
Any class which inherits from SomeClass must implement aMethod, or it too becomes an abstract base class which cannot be instantiated
Note that any class with one or more pure virtual functions is automatically an abstract base class.
The "equals 0" you're referring to is called "pure virtual". It's a function that the child that wants to be instantiated HAS to implement as opposed to providing base functionality meaning that the parent class is going to define functionality that has to exist but that the parent has no knowledge of how the child will do it. Note that this makes the class abstract in that it cannot be instantiated. For example I may want to define a "Mammal" class I can inherit from and I want its children to act a certain way - but I can't simply make a "Mammal". Instead I would create a "Giraffe" class and make sure it acts like it's supposed to.
It's also explained at this SO question.
The "Empty" function you're referring to is instead functionality where the function is defined and can be called - but does nothing.
the declaration aMethod()=0 tells the compiler that this method must be provided for in subclasses. Any subclass that does not implement the method can not be instantiated. This helps you ensure any objects of the base class will have the method implemented.
A pure virtual function (your first example, with the =0) means that function must be overridden in a derived class for an object of that class to be instantiated.
The second is basically just a member function that does nothing. Since the function has a different name and the class isn't related to SomeClass, the two don't affect each other at all.
The third overrides the pure virtual function, so it's possible to instantiate SomeClassSon, but in the derived class the overridden function does nothing.
A pure virtual makes the class abstract. An empty non-virtual method doesn't do anything - it just leads to a linker error if you attempt to call it. By contrast, you can't attempt to call a pure virtual (unless you attempt to call it from a constructor, which is bad anyway) because the compiler won't let you create that object.
There's also a logical difference - the method marked virtual will be virtual through the inheritance chain - the others are just regular methods.
Sometimes I accidentally forget to call the superclass's method in C++ when I override a method.
Is there any way to help figure out when I'm overriding a method with, so that I don't forget to call the superclass's method? (Something like Java's #Override, except that C++ doesn't have annotations...)
One suggestion is the Non-Virtual Inferface Idiom. I.e., make your public methods non-virtual and have them call private or protected virtual methods that derived classes can override to implement their specific behavior.
If you don't have control over the base class, you could perhaps use an intermediate class:
class Foo // Don't control this one
{
public:
virtual void action();
};
class Bar : public Foo // Intermediate base class
{
public:
virtual void action()
{
doAction();
Foo::action();
}
protected:
virtual void doAction() = 0;
};
Derive your classes from Bar and override doAction() on each. You could even have doBeforeAction() and doAfterAction() if necessary.
With regards to Java's #Override, there is a direct equivalent in C++11, namely the override special identifier.
Sadly, neither #Override nor override solve the problem since: (a) they're optional; (b) the responsibility of calling the base class's method still rests with the programmer.
Furthermore, I don't know of any widely available method that would address the problem (it's quite tricky, esp. given that you don't necessarily want to call the base class's method -- how is the machine to know?).
Unfortunately Í'm not aware of a common mechanism to do this.
In C++ if you're needing to use the base class's functionality in addition to added child functionality you should look at the template method pattern. This way the common logic always lives in the base class and there's no way to forget to execute it, and you override in the child only the piece you need to change.
When I declare a base class, should I declare all the functions in it as virtual, or should I have a set of virtual functions and a set of non-virtual functions which I am sure are not going to be inherited?
A function only needs to be virtual iff a derived class will implement that function in a different way.
For example:
class Base {
public:
void setI (int i) // No need for it to be virtual
{
m_i = i;
}
virtual ~Base () {} // Almost always a good idea
virtual bool isDerived1 () // Is overridden - so make it virtual
{
return false;
}
private:
int m_i;
};
class Derived1 : public Base {
public:
virtual ~Derived () {}
virtual bool isDerived1 () // Is overridden - so make it virtual
{
return true;
}
};
As a result, I would error the side of not having anything virtual unless you know in advance that you intend to override it or until you discover that you require the behaviour. The only exception to this is the destructor, for which its almost always the case that you want it to be virtual in a base class.
You should only make functions you intend and design to be overridden virtual. Making a method virtual is not free in terms of both maintenance and performance (maintenance being the much bigger issue IMHO).
Once a method is virtual it becomes harder to reason about any code which uses this method. Because instead of considering what one method call would do, you must consider what N method calls would do in that scenario. N represents the number of sub classes which override that method.
The one exception to this rule is destructors. They should be virtual in any class which is intended to be derived from. It's the only way to guarantee that the proper destructor is called during deallocation.
The non-virtual interface idiom (C++ Coding Standards item 39) says that a base class should have non-virtual interface methods, allowing the base class to guarantee invariants, and non-public virtual methods for customization of the base class behaviour by derived classes. The non-virtual interface methods call the virtual methods to provide the overridable behaviour.
I tend to make only the things I want to be overridable virtual. If my initial assumptions about what I will want to override turn out to be wrong, I go back and change the base class.
Oh, and obviously always make your destructor virtual if you're working on something that will be inherited from.
If you are creating a base class ( you are sure that somebody derives the class ) then you can do following things:
Make destructor virtual (a must for base class)
Define methods which should be
derived and make them virtual.
Define methods which need not be ( or
should not be) derived as
non-virtual.
If the functions are only for derived
class and not for base class then mark
them as protected.
Compiler wouldn't know which actual piece of code will be run when pointer of base type calls a virtual function. so the actual piece of code that would be run needs to be evaluated at run-time according to which object is pointed by base class pointer. So avoid the use of virtual function if the function is not gonne be overriden in an inherited class.
TLDR version:
"you should have a set of virtual functions and a set of non-virtual functions which you are sure are not going to be inherited." Because virtual functions causes a performance decrease at run-time.
The interface functions should be, in general, virtual. Functions that provide fixed functionality should not.
Why declare something virtual until you are really overriding it? I believe it's not a question of being sure or not. Follow the facts: is it overriden somewhere? No? Then it must not be virtual.