I have three different implementations of an interface (solving systems of equations). The old interface essentially was void foo(int *f)
within a class. Now I want to generalize this to a case where I solve N
systems at the same time. For this I want to have the interface void foo(int *f[N]
).
In the codebase there is an abstract class defining the interface, then three classes derive from that class. I would like to add my generalization without breaking existing code. Therefore I thought of adding the new interface and have the old interface delegate to the new one. This is my compressed version:
#include <iostream>
struct AbstractClass {
/// Old interface, needs to be retained.
virtual void foo(int *f) {
std::cout << "AbstractClass::foo(int *f)\n";
int *a[2] = {f, nullptr};
foo(a);
}
/// New interface.
virtual void foo(int *f[2]) {
std::cout << "AbstractClass::foo(int *f[2])\n";
}
};
struct Derived : public AbstractClass {
/// New interface.
void foo(int *f[2]) override {
std::cout << "Derived::foo(int *f[2])\n";
}
};
int main(int argc, char **argv) {
// Code using the old interface.
Derived d;
int *a;
d.foo(a);
}
My hope is that the call of d.foo(a)
would go to the inherited Derived::foo(int *f)
and from there to Derived::foo(int *f[2])
. However, g++
6.3 gives me the following (in C++11 mode):
inheritance-test.cpp: In function 'int main(int, char**)':
inheritance-test.cpp:31:12: error: no matching function for call to 'Derived::foo(int*&)'
d.foo(a);
^
inheritance-test.cpp:21:10: note: candidate: virtual void Derived::foo(int**)
void foo(int *f[2]) override {
^~~
inheritance-test.cpp:21:10: note: no known conversion for argument 1 from 'int*' to 'int**'
It looks like the derived objects do not really have inherited the methods that I want.
Using runtime polymorphism with a pointer to the base class does work, though:
AbstractClass *pd = new Derived();
int *a = nullptr;
pd->foo(a);
delete pd;
I do not really understand why it does not work without the pointer. The vtable is not used with automatic storage because the function calls are bound at compile time (early binding)?
This is getting me a bit closer to the solution, but I would still have to touch all the code which uses this library. However, that is not really an option, the old stuff has to keep working.
What can I do about that (other than duplicating all code)? Would it be sufficient to have this delegation copied into each derived class?