override c++ virtual method - c++

I have a class template where some methods are defined as virtual to give the ability for the user of my class to give an implementation for them in his derived class. Note that in my template class there is some non-virtual methods that makes use of the virtual one (a virtual class that should return a value is called in a non-virtual class).
Can you give me a simple example of a correct code where the virtual method of the parent class should return a value (but it's implementation is provided in a child class) and the value returned by the virtual method in the parent class is used in other methods of that class. Because I saw somewhere (for example here: Safely override C++ virtual functions) that this can cause some problems and the user defined method will note override the virtual method of the parent class.
Note: I program with Code::Blocks using g++ compiler.
EDIT: as requested here a simple example of what I want:
template<typename T>
class parent {
public:
// Public methods that user can call
int getSomething(T t);
void putSomething(T t, int x);
// public method that user should implement in his code
virtual float compute(T t) { }
// protected or private methods and attributes used internally by putSomething ...
float doComplexeThings(...); // this can call
};
The method compute() should be implemented by the user (the child class). However, this method compute() is called by putSomething() and doComplexeThings() for example.

If you can use C++11 features in your compiler then overrides can be tagged as so with the override special identifier:
float compute() override;
The above line in a derived class will cause a compiler error as the function does not override a member function in the base (incorrect signature, missing argument). But note that this must be done in each derived class, it is not a solution that you can impose from the base class.
From the base class you can only force the override by making the function pure virtual, but that changes the semantics. It does not avoid problems while overriding, but rather forces overriding in all cases. I would avoid this approach, and if you are to follow it and there is a sensible implementation for the base type, make the function virtual and provide a definition so that your derived classes's implementation can just call the functions the base type (i.e. you force the implementation, but in the simplest cases it will just forward the call to the parent)

You just have to make sure that the methods have the same signature (including const/mutable modifiers and argument types). You can use a pure virtual definition to provoke compiler errors if you fail to override the function in a subclass.
class parent {
public:
// pure virtual method must be provided in subclass
virtual void handle_event(int something) = 0;
};
class child : public parent {
public:
virtual void handle_event(int something) {
// new exciting code
}
};
class incomplete_child : public parent {
public:
virtual void handle_event(int something) const {
// does not override the pure virtual method
}
};
int main() {
parent *p = new child();
p->handle_event(1); // will call child::handle_event
parent *p = new incomplete_child(); // will not compile because handle_event
// was not correctly overridden
}

This question is asked in 2013. It's pretty old but I found something new which doesn't exist in the answers.
We need to understanding three concept is overload, overwrite, and hide.
Short answer, you want to overload the inheritance function from base class.
However, overload is the mechanism to add multiple behavior for function which needs all these functions under the same scale. But the virtual function is in the Base class obviously.
class A {
public:
virtual void print() {
cout << id_ << std::endl;
}
private:
string id_ = "A";
};
class B : A {
public:
using A::print;
void print(string id) {
std::cout << id << std::endl;
}
};
int main(int argc, char const *argv[]) {
/* code */
A a;
a.print();
B b;
b.print();
b.print("B");
return 0;
}
Add using A::print; in your derive class will do the work!
Though I don't feel it's a good idea since the philosophy behind the overload and inheritance is different, it may not a good idea to nest them together.

Related

What are the advantages of having a definition of pure virtual method In C++? [duplicate]

I did a simple test today:
struct C{virtual void f()=0;};
void C::f(){printf("weird\n");}
The program is OK, but is weird to me, when we use =0 it means the function body should be defined in the inherited classes, but it seems I can still give it implementation function.
I tried both GCC and VC, both OK. So it seems to me this should be part of C++ standard.
But why this is not a syntax error?
A reason I could think of is like C# having both 'interface' and 'abstract' keywords, interface can't have an implementation, while abstract could have some implementations.
Is this the case for my confusion, that C++ should support such a kind of weird syntax?
C++ Supports pure virtual functions with an implementation so class designers can force derived classes to override the function to add specific details , but still provide a useful default implementation that they can use as a common base.
Classic example:
class PersonBase
{
private:
string name;
public:
PersonBase(string nameIn) : name(nameIn) {}
virtual void printDetails() = 0
{
std::cout << "Person name " << name << endl;
}
};
class Student : public PersonBase
{
private:
int studentId;
public:
Student(string nameIn, int idIn) : PersonBase(nameIn), studentId(idIn) { }
virtual void printDetails()
{
PersonBase::printDetails(); // call base class function to prevent duplication
std::cout << "StudentID " << studentId << endl;
}
};
Others mentioned language consistency with the destructor, so I'll go for a software engineering stand-point:
It's because the class you are defining may have a valid default implementation, but calling it is risky/expansive/whatever. If you don't define it as pure virtual, derived classes will inherit that implementation implicitly. And may never know until run-time.
If you define it as pure virtual, a derived class must implement the function. And if it's okay with the risk/cost/whatever, it can call the default implementation statically as Base::f();
What's important is that it's a conscious decision, and the call is explicit.
Basically, the best of both worlds (or the worst...).
The derived class is required to implement the pure virtual method, the designer of the base class requires this for some reason. And the base class also provides a default implementation of this method that, if the derived class desires or requires it, can be used.
So some sample code could look like;
class Base {
public:
virtual int f() = 0;
};
int Base::f() {
return 42;
}
class Derived : public Base {
public:
int f() override {
return Base::f() * 2;
}
};
So what is a common use case...
A common use case for this technique is related to the destructor - basically the designer of the base class desires that it is an abstract class, but none of the methods make much sense as being pure virtual functions. The destructor is a feasible candidate.
class Base {
public:
~Base() = 0;
};
Base::~Base() { /* destruction... */ }
A pure virtual function must be overriden in subclasses. However, you can provide a default-implementation, that will work for sub-classes, but might not be optimal.
A constructed use case is for abstract shapes, e.g.
class Shape {
public:
virtual Shape() {}
virtual bool contains(int x, int y) const = 0;
virtual int width() const = 0;
virtual int height() const = 0;
virtual int area() const = 0;
}
int Shape::area() const {
int a = 0;
for (int x = 0; x < width(); ++x) {
for (int y = 0; y < height(); ++y) {
if (contains(x,y)) a++;
}
}
return a;
}
The area method will work for any shape, but is highly inefficient. Subclassers are encouraged to provide a suitable implementation, but if there is none available, they still can explicitely call the base class's method
Pure virtual means "child must override".
So:
struct A{ virtual void foo(){}; };
struct B:A{ virtual void foo()=0; };
struct C:B{ virtual void foo(){}; };
struct D:C{ virtual void foo()=0; };
void D::foo(){};
struct E:D{ virtual void foo(){D::foo();}; };
A has a virtual foo.
B makes it abstract. Before making an instance, derived types must implement it now.
C implements it.
D makes it abstract, and adds an imllementation.
E implements it by calling D's implementation.
A, C and E can have instances created. B and D cannot.
The technique of abstract with implementation can be used to provide a partial or inefficient implementation that derived types can call explicitly when they want to use it, but do not get "by default" because that would be ill advised.
Another intersting use case is where the parent interface is in flux, and tue code base is large. It has a fully functional implementation. Children who use the default must repeat the signature and forward explicitly to it. Those that want to override simply override.
When the base class sigrnature changes, the code will fail to compile unless every child either explicitly calls the default or properly overrides. Prior to the override keyword this was the only way to ensure you did not accidentally create a new virtual function instead of overriding a parent, and it remains the only way where the policy is enforced in the parent type.
Please note that you cannot instantiate an object with pure virtual methods.
Try to instantiate:
C c;
with VC2015, there is an error as expected:
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): error C2259: 'C': cannot instantiate abstract class
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): note: due to following members:
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): note: 'void C::f(void)': is abstract
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(6): note: see declaration of 'C::f'
To answer your question:
The mechanisms only declares the function to be pure virtual, but there is still the virtual function table and the baseclass. It will avoid you instanciate Baseclass (C), but does not avoid using it:
struct D : public C { virtual void f(); };
void D::f() { printf("Baseclass C::f(): "); C::f(); }
...
D d;
d.f();
The destructor must be defined, even if it is pure virtual. If you don't define the destructor the compiler will generate one.
Edit: you can't leave destructor declared without define, will cause link error.
You can anyway call the body of the function from derived classes.
You can implement the body of a pure virtual function to provide a default behavior, and at the same time you want that the designer of the derived class use that function explicitly.

How do I specify a C++ virtual function that is guaranteed to be called by any overriding function? [duplicate]

One very common mistake with class hierarchies is to specify a method in a base class as being virtual, in order for all overrides in the inheritance chain to do some work, and forgetting to propagate the call on to base implementations.
Example scenario
class Container
{
public:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Nothing to do here
}
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Set some property of pObject and pass on.
Container::PrepareForInsertion(pObject);
}
};
class MoreSpecializedContainer : public SpecializedContainer
{
protected:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Oops, forgot to propagate!
}
};
My question is: is there a good way/pattern to ensure that the base implementation always gets called at the end of the call chain?
I know of two methods to do this.
Method 1
You can use a member variable as a flag, set it to the correct value in the base implementation of the virtual method, and check its value after the call. This requires to use a public non-virtual method as interface for the clients, and making the virtual method protected (which is actually a good thing to do), but it requires the use of a member variable specifically for this purpose (which needs to be mutable if the virtual method must be const).
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
m_callChainCorrect = false;
PrepareForInsertionImpl(pObject);
assert(m_callChainCorrect);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
m_callChainCorrect = true;
}
private:
bool m_callChainCorrect;
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// Do something and pass on
Container::PrepareForInsertionImpl(pObject);
}
};
Method 2
The other way to do it is to replace the member variable with an opaque "cookie" parameter and do the same thing:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
bool callChainCorrect = false;
PrepareForInsertionImpl(pObject, &callChainCorrect);
assert(callChainCorrect);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject, void* pCookie)
{
*reinrepret_cast<bool*>(pCookie) = true;
}
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject, void* pCookie)
{
// Do something and pass on
Container::PrepareForInsertionImpl(pObject, pCookie);
}
};
This approach is inferior to the first one in my opinion, but it does avoid the use of a dedicated member variable.
What other possibilities are there?
You've come up with some clever ways to do this, at (as you acknowledge) the cost of bloating the class and adding code that addresses not the object's responsibilities but programmer deficiences.
The real answer is not to do this at runtime. This is a programmer error, not a runtime error.
Do it at compile time: use a language construct if the language supports it, or use a Pattern the enforces it (e.g,, Template Method), or make your compilation dependent on tests passing, and set up tests to enforce it.
Or, if failing to propagate causes the derived class to fail, let it fail, with an exception message that informs the author of the derived class that he failed to use the base class correctly.
What you are looking for is simply the Non-Virtual Interface pattern.
It's similar to what you are doing here, but the base class implementation is guaranteed to be called because it's the only implementation that can be called. It eliminates the clutter that your examples above require. And the call through the base class is automatic, so derived versions don't need to make an explicit call.
Google "Non-Virtual Interface" for details.
Edit: After looking up "Template Method Pattern", I see that it's another name for Non-Virtual Interface. I've never heard it referred to by the name before (I'm not exactly a card-carrying member of the GoF fan club). Personally, I prefer the name Non-Virtual Interface because the name itself actually describes what the pattern is.
Edit Again: Here's the NVI way of doing this:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
PrepareForInsertionImpl(pObject);
// If you put some base class implementation code here, then you get
// the same effect you'd get if the derived class called the base class
// implementation when it's finished.
//
// You can also add implementation code in this function before the call
// to PrepareForInsertionImpl, if you want.
}
private:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject) = 0;
};
class SpecializedContainer : public Container
{
private:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// Do something and return to the base class implementation.
}
};
When there's only one level of inheritance you can use the template method pattern where the public interface is non-virtual and calls a virtual implementation function. Then the base's logic goes in the public function which is assured to be called.
If you have more than one level of inheritance and want each class to call its base class then you can still use the template method pattern, but with a twist, make the return value of the virtual function only constructable by base so derived will be forced to call the base implementation in order to return a value (enforced at compile time).
This doesn't enforce that each class calls its direct base class, it may skip a level (I can't think of a good way to enforce that) but it does force the programmer to make a conscious decision, in other words it works against inattentiveness not malice.
class base {
protected:
class remember_to_call_base {
friend base;
remember_to_call_base() {}
};
virtual remember_to_call_base do_foo() {
/* do common stuff */
return remember_to_call_base();
}
remember_to_call_base base_impl_not_needed() {
// allow opting out from calling base::do_foo (optional)
return remember_to_call_base();
}
public:
void foo() {
do_foo();
}
};
class derived : public base {
remember_to_call_base do_foo() {
/* do specific stuff */
return base::do_foo();
}
};
If you need the public (non virtual) function to return a value the inner virtual one should return std::pair<return-type, remember_to_call_base>.
Things to note:
remember_to_call_base has an explicit constructor declared private so only its friend (in this case base) can create a new instance of this class.
remember_to_call_base doesn't have an explicitly defined copy constructor so the compiler will create one with public accessibility which allows returning it by value from the base implementation.
remember_to_call_base is declared in the protected section of base, if it was in the private section derived won't be able to reference it at all.
A completely different approach would be to register functors. Derived classes would register some function (or member function) with the base class while in the derived class constructor. When the actual function is called by the client it is a base class function which then iterates through the registered functions. This scales to many levels of inheritance, each derived class only has to be concerned with its own function.
Look at the template method pattern. (The basic idea is that you don't have to call the base class method anymore.)
One way out is to not use virtual methods at all, but instead to allow the user to register callbacks, and call those before doing the work of prepareForInsertion. This way it becomes impossible to make that mistake since it is the base class that makes sure that both the callbacks and the normal processing happen. You can end up with a lot of callbacks if you want this behaviour for a lot of functions. If you really do use that pattern so much, you might want to look into tools like AspectJ (or whatever the C# equivalent is) that can automate this sort of thing.
If you found out you can hide virtual function and make interface non-virtual, try instead of checking if other users did call your function just call it by yourself. If your base code should be called at the end, it would look like this:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
PrepareForInsertionImpl(pObject);
doBasePreparing(pObject);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// nothing to do
}
private:
void doBasePreparing(ObjectToInsert* pObject)
{
// put here your code from Container::PrepareForInsertionImpl
}
};

Why does C++ support pure virtual functions with an implementation?

I did a simple test today:
struct C{virtual void f()=0;};
void C::f(){printf("weird\n");}
The program is OK, but is weird to me, when we use =0 it means the function body should be defined in the inherited classes, but it seems I can still give it implementation function.
I tried both GCC and VC, both OK. So it seems to me this should be part of C++ standard.
But why this is not a syntax error?
A reason I could think of is like C# having both 'interface' and 'abstract' keywords, interface can't have an implementation, while abstract could have some implementations.
Is this the case for my confusion, that C++ should support such a kind of weird syntax?
C++ Supports pure virtual functions with an implementation so class designers can force derived classes to override the function to add specific details , but still provide a useful default implementation that they can use as a common base.
Classic example:
class PersonBase
{
private:
string name;
public:
PersonBase(string nameIn) : name(nameIn) {}
virtual void printDetails() = 0
{
std::cout << "Person name " << name << endl;
}
};
class Student : public PersonBase
{
private:
int studentId;
public:
Student(string nameIn, int idIn) : PersonBase(nameIn), studentId(idIn) { }
virtual void printDetails()
{
PersonBase::printDetails(); // call base class function to prevent duplication
std::cout << "StudentID " << studentId << endl;
}
};
Others mentioned language consistency with the destructor, so I'll go for a software engineering stand-point:
It's because the class you are defining may have a valid default implementation, but calling it is risky/expansive/whatever. If you don't define it as pure virtual, derived classes will inherit that implementation implicitly. And may never know until run-time.
If you define it as pure virtual, a derived class must implement the function. And if it's okay with the risk/cost/whatever, it can call the default implementation statically as Base::f();
What's important is that it's a conscious decision, and the call is explicit.
Basically, the best of both worlds (or the worst...).
The derived class is required to implement the pure virtual method, the designer of the base class requires this for some reason. And the base class also provides a default implementation of this method that, if the derived class desires or requires it, can be used.
So some sample code could look like;
class Base {
public:
virtual int f() = 0;
};
int Base::f() {
return 42;
}
class Derived : public Base {
public:
int f() override {
return Base::f() * 2;
}
};
So what is a common use case...
A common use case for this technique is related to the destructor - basically the designer of the base class desires that it is an abstract class, but none of the methods make much sense as being pure virtual functions. The destructor is a feasible candidate.
class Base {
public:
~Base() = 0;
};
Base::~Base() { /* destruction... */ }
A pure virtual function must be overriden in subclasses. However, you can provide a default-implementation, that will work for sub-classes, but might not be optimal.
A constructed use case is for abstract shapes, e.g.
class Shape {
public:
virtual Shape() {}
virtual bool contains(int x, int y) const = 0;
virtual int width() const = 0;
virtual int height() const = 0;
virtual int area() const = 0;
}
int Shape::area() const {
int a = 0;
for (int x = 0; x < width(); ++x) {
for (int y = 0; y < height(); ++y) {
if (contains(x,y)) a++;
}
}
return a;
}
The area method will work for any shape, but is highly inefficient. Subclassers are encouraged to provide a suitable implementation, but if there is none available, they still can explicitely call the base class's method
Pure virtual means "child must override".
So:
struct A{ virtual void foo(){}; };
struct B:A{ virtual void foo()=0; };
struct C:B{ virtual void foo(){}; };
struct D:C{ virtual void foo()=0; };
void D::foo(){};
struct E:D{ virtual void foo(){D::foo();}; };
A has a virtual foo.
B makes it abstract. Before making an instance, derived types must implement it now.
C implements it.
D makes it abstract, and adds an imllementation.
E implements it by calling D's implementation.
A, C and E can have instances created. B and D cannot.
The technique of abstract with implementation can be used to provide a partial or inefficient implementation that derived types can call explicitly when they want to use it, but do not get "by default" because that would be ill advised.
Another intersting use case is where the parent interface is in flux, and tue code base is large. It has a fully functional implementation. Children who use the default must repeat the signature and forward explicitly to it. Those that want to override simply override.
When the base class sigrnature changes, the code will fail to compile unless every child either explicitly calls the default or properly overrides. Prior to the override keyword this was the only way to ensure you did not accidentally create a new virtual function instead of overriding a parent, and it remains the only way where the policy is enforced in the parent type.
Please note that you cannot instantiate an object with pure virtual methods.
Try to instantiate:
C c;
with VC2015, there is an error as expected:
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): error C2259: 'C': cannot instantiate abstract class
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): note: due to following members:
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): note: 'void C::f(void)': is abstract
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(6): note: see declaration of 'C::f'
To answer your question:
The mechanisms only declares the function to be pure virtual, but there is still the virtual function table and the baseclass. It will avoid you instanciate Baseclass (C), but does not avoid using it:
struct D : public C { virtual void f(); };
void D::f() { printf("Baseclass C::f(): "); C::f(); }
...
D d;
d.f();
The destructor must be defined, even if it is pure virtual. If you don't define the destructor the compiler will generate one.
Edit: you can't leave destructor declared without define, will cause link error.
You can anyway call the body of the function from derived classes.
You can implement the body of a pure virtual function to provide a default behavior, and at the same time you want that the designer of the derived class use that function explicitly.

Inheritance with an override function

I'm looking at some C++ example code, which effectively has the following:
class Foo : public mynamespace::Bar
{
public:
Foo()
{
// Do some stuff
}
void Delta() override
{
// Do some stuff
Bar::Delta();
}
};
I am having trouble understanding why the line Bar::Delta(); exists. Given that class Foo inherits class Bar, then surely when Foo::Delta() is called, this overrides anything existing in Bar::Delta(), and hence this line is redundant.
Or am I misunderstanding this whole inheritance thing? Maybe override doesn't override everything?
Bar::Delta();
is a function call. Isn't that what it looks like?
It's calling the base class version of Delta - by explicitly qualifying it as Bar::Delta - in addition to whatever extra stuff Foo's version does.
Maybe override doesn't override everything?
The override keyword just asks the compiler to verify you're really overriding a virtual function - otherwise, it's easy to accidentally write a new function which doesn't override anything (eg. because a parameter type is slightly different, or one version is const-qualified, or you changed the base class and forgot to update the derived class, or ...).
Here you are overriding the virtual function. That doesn't stop the base class implementation from existing, and as you've seen you can still call it.
You can (and should) test your intuition about this sort of thing yourself. Consider the trivial test code below. What do you think it will do?
Now actually run it. Were you right? If not, which part was unexpected?
#include <iostream>
using namespace std;
struct Bar {
virtual void Delta() {
cout << "Bar::Delta\n";
}
};
struct Foo : public Bar {
void Delta() override
{
cout << "Foo::Delta\n";
Bar::Delta();
}
};
int main()
{
cout << "b.Delta()\n";
Bar b;
b.Delta();
cout << "f.Delta()\n";
Foo f;
f.Delta();
cout << "pb->Delta()\n";
Bar *pb = &b;
pb->Delta();
cout << "pb->Delta()\n";
pb = &f;
pb->Delta();
}
This is a common pattern. In fact, the :: syntax for calling an overridden member function is there specifically for this situation.
It is very common for member function in a base class to perform some computation or action which can be done independently of the derived class, and let the derived class do things specific to the derivation.
Here is a fictitious example:
class Stock {
protected:
double totalDividend;
double baseDividend;
double adjustmentFactor;
public:
Stock(double d, double a)
: baseDividend(d), totalDividend(d), adjustmentFactor(a) {
}
virtual void double ComputeDividend() {
return totalDividend * adjustmentFactor;
}
};
class SpecialStock {
private:
double specialDividend;
public:
SpecialStock(double d, double sd, double a)
: Stock(d, a), specialDividend(sd) {
}
virtual void double ComputeDividend() override {
// Do some preparations
totalDividend = baseDividend + specialDividend;
// Call the overridden function from the base class
return Stock::ComputeDividend();
}
};
You seem to misunderstand what override means in c++. You should not really bother by it for your case. It's like a normal virtual function. override keyword is just a safety mechanism to ensure that a base class has matching function. It doesn't change anything other than semantic compile-time checks.
It is somewhat useful to guard against typical mismatches, such a const vs non-const versions, etc.
The virtual method mechanism does not replace the original member functions. It still is there in the Derived object. What happens is that a level of indirection is introduced, so a call to base.foo() uses a function pointer to call correct implementation which is Derived::Foo() in your case. But Base::Foo() still exists, and this is the syntax to "access" it. You can look up how exactly it work by searching materials on virtual methods.
Maybe override doesn't override everything?
The override specifier can be used to make compile-time checks when overriding a function that the function being overridden is virtual and is in fact being overridden.
why the line Bar::Delta(); exists
This line calls the base Delta function which might have some useful tasks to perform even though you have overridden it.
A simple example:
class Base
{
public:
virtual ~Base() {}
virtual void Foo()
{
// run tasks that are common to all derived types
}
};
class Derived : public Base
{
public:
void Foo() override
{
Base::Foo(); // we have to call this explicitly
// run tasks specific to the derived type
}
};
Delta in foo is a virtual method which "does some stuff" and then calls the base class's implementation of Delta.
override does not override anything, declaring the method as virtual does that. override is just for the compiler to throw syntax error in case the parent class doesn't have the Delta method.

How to ensure that virtual method calls get propagated all the way to the base class?

One very common mistake with class hierarchies is to specify a method in a base class as being virtual, in order for all overrides in the inheritance chain to do some work, and forgetting to propagate the call on to base implementations.
Example scenario
class Container
{
public:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Nothing to do here
}
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Set some property of pObject and pass on.
Container::PrepareForInsertion(pObject);
}
};
class MoreSpecializedContainer : public SpecializedContainer
{
protected:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Oops, forgot to propagate!
}
};
My question is: is there a good way/pattern to ensure that the base implementation always gets called at the end of the call chain?
I know of two methods to do this.
Method 1
You can use a member variable as a flag, set it to the correct value in the base implementation of the virtual method, and check its value after the call. This requires to use a public non-virtual method as interface for the clients, and making the virtual method protected (which is actually a good thing to do), but it requires the use of a member variable specifically for this purpose (which needs to be mutable if the virtual method must be const).
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
m_callChainCorrect = false;
PrepareForInsertionImpl(pObject);
assert(m_callChainCorrect);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
m_callChainCorrect = true;
}
private:
bool m_callChainCorrect;
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// Do something and pass on
Container::PrepareForInsertionImpl(pObject);
}
};
Method 2
The other way to do it is to replace the member variable with an opaque "cookie" parameter and do the same thing:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
bool callChainCorrect = false;
PrepareForInsertionImpl(pObject, &callChainCorrect);
assert(callChainCorrect);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject, void* pCookie)
{
*reinrepret_cast<bool*>(pCookie) = true;
}
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject, void* pCookie)
{
// Do something and pass on
Container::PrepareForInsertionImpl(pObject, pCookie);
}
};
This approach is inferior to the first one in my opinion, but it does avoid the use of a dedicated member variable.
What other possibilities are there?
You've come up with some clever ways to do this, at (as you acknowledge) the cost of bloating the class and adding code that addresses not the object's responsibilities but programmer deficiences.
The real answer is not to do this at runtime. This is a programmer error, not a runtime error.
Do it at compile time: use a language construct if the language supports it, or use a Pattern the enforces it (e.g,, Template Method), or make your compilation dependent on tests passing, and set up tests to enforce it.
Or, if failing to propagate causes the derived class to fail, let it fail, with an exception message that informs the author of the derived class that he failed to use the base class correctly.
What you are looking for is simply the Non-Virtual Interface pattern.
It's similar to what you are doing here, but the base class implementation is guaranteed to be called because it's the only implementation that can be called. It eliminates the clutter that your examples above require. And the call through the base class is automatic, so derived versions don't need to make an explicit call.
Google "Non-Virtual Interface" for details.
Edit: After looking up "Template Method Pattern", I see that it's another name for Non-Virtual Interface. I've never heard it referred to by the name before (I'm not exactly a card-carrying member of the GoF fan club). Personally, I prefer the name Non-Virtual Interface because the name itself actually describes what the pattern is.
Edit Again: Here's the NVI way of doing this:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
PrepareForInsertionImpl(pObject);
// If you put some base class implementation code here, then you get
// the same effect you'd get if the derived class called the base class
// implementation when it's finished.
//
// You can also add implementation code in this function before the call
// to PrepareForInsertionImpl, if you want.
}
private:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject) = 0;
};
class SpecializedContainer : public Container
{
private:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// Do something and return to the base class implementation.
}
};
When there's only one level of inheritance you can use the template method pattern where the public interface is non-virtual and calls a virtual implementation function. Then the base's logic goes in the public function which is assured to be called.
If you have more than one level of inheritance and want each class to call its base class then you can still use the template method pattern, but with a twist, make the return value of the virtual function only constructable by base so derived will be forced to call the base implementation in order to return a value (enforced at compile time).
This doesn't enforce that each class calls its direct base class, it may skip a level (I can't think of a good way to enforce that) but it does force the programmer to make a conscious decision, in other words it works against inattentiveness not malice.
class base {
protected:
class remember_to_call_base {
friend base;
remember_to_call_base() {}
};
virtual remember_to_call_base do_foo() {
/* do common stuff */
return remember_to_call_base();
}
remember_to_call_base base_impl_not_needed() {
// allow opting out from calling base::do_foo (optional)
return remember_to_call_base();
}
public:
void foo() {
do_foo();
}
};
class derived : public base {
remember_to_call_base do_foo() {
/* do specific stuff */
return base::do_foo();
}
};
If you need the public (non virtual) function to return a value the inner virtual one should return std::pair<return-type, remember_to_call_base>.
Things to note:
remember_to_call_base has an explicit constructor declared private so only its friend (in this case base) can create a new instance of this class.
remember_to_call_base doesn't have an explicitly defined copy constructor so the compiler will create one with public accessibility which allows returning it by value from the base implementation.
remember_to_call_base is declared in the protected section of base, if it was in the private section derived won't be able to reference it at all.
A completely different approach would be to register functors. Derived classes would register some function (or member function) with the base class while in the derived class constructor. When the actual function is called by the client it is a base class function which then iterates through the registered functions. This scales to many levels of inheritance, each derived class only has to be concerned with its own function.
Look at the template method pattern. (The basic idea is that you don't have to call the base class method anymore.)
One way out is to not use virtual methods at all, but instead to allow the user to register callbacks, and call those before doing the work of prepareForInsertion. This way it becomes impossible to make that mistake since it is the base class that makes sure that both the callbacks and the normal processing happen. You can end up with a lot of callbacks if you want this behaviour for a lot of functions. If you really do use that pattern so much, you might want to look into tools like AspectJ (or whatever the C# equivalent is) that can automate this sort of thing.
If you found out you can hide virtual function and make interface non-virtual, try instead of checking if other users did call your function just call it by yourself. If your base code should be called at the end, it would look like this:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
PrepareForInsertionImpl(pObject);
doBasePreparing(pObject);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// nothing to do
}
private:
void doBasePreparing(ObjectToInsert* pObject)
{
// put here your code from Container::PrepareForInsertionImpl
}
};