We have a large software framework where, in the heavy-lifting part of the code, we have an abstract base class, say
class Base {
public:
virtual double eval() const = 0;
};
which pretty much acts as a common interface class for many other classes spread all over various sub-packages, residing in different repositories and whatnot.
class Derived1 {
public:
virtual double eval() const override { return 1; }
}
However, there is really only one place where this function is called in our code, which is in the main loop of the core application.
int main(int argc, char* argv[]){
Base* x = createInstance(argv[1]); // some factory function
while(true){
std::cout << x->eval() << std::endl;
}
}
We recently discovered that it would be very useful to extend the interface such:
virtual double eval(int idx) const = 0;
Fixing the one call to this method in the core application is not the problem, but fixing the dozens of existing derived class implementations spread all over our code to accept and (in most cases) ignore this new parameter will be a nightmare.
I've thought about providing a legacy wrapper that would look like this:
double Base::eval(int idx) const { return this->eval(); }
But this would mean that all derived classes would need to implement the non-argument version of this function to exist, even though it's supposed to be deprecated. Alternatively, we could implement the non-argument version as a part of Base
, but then we would sacrifice the abstract nature of Base
, because then all components would be implemented already there.
Is there any "neat" way to solve this problem, or is the only sane thing to actually contact all the subpackage developers and make them change their implementations to adhere to the new interface?