Reputation: 401
The current situation is this: I am going through some code re factoring
If you look at the image the current situation is that I have a virtual method setData(int ID);
now we want to change that to a virtual method setData(dataObj aObj);
But doing so, is a long process since, our foo
object has been inherited by tons of classes. So, we want to gradually make the code change.
As such, what I need to do is to check if one of the inherited classes has implemented
setData(dataObj aObj)
call that class, else call the other previous function signature
setData(int ID);
The problem is further complicated by the fact that, FOO
class provides a default setData(int ID)
previously and not all classes that inherit from FOO
thus may/may not need to implement setData
and their implementations do vary wildly.
I have already looked at How to Check if the function exists in C/C++ unfortunately, that does not answer my questions.
In some of the posts I have seen people use templates, that's not an option for me, since this needs to be done at runtime. The other options seems to suggest linking /mangling tricks with GCC etc. I need to build my code to be platform and compiler independent. So that's not an option either.
Any more suggestions, the only possible close solution seems to be https://stackoverflow.com/a/8814800/1376317 But I am really not sure how to implement this in my workflow, or whether this is even relevant to my problem.
Upvotes: 1
Views: 782
Reputation: 135
If modifying dataObj class is an option, and creating and destroying dataObj objects are not too expensive, then you can consider the following. I don't particularly like it but as far as short term hacks go, I have seen worse...
class dataObj
{
int x;
public:
int getID(void) const {
std::cout << "dataObj::getID " << std::endl;
return x;
}
dataObj() : x(0){}
~dataObj(){}
};
class Foo
{
public:
// Old interface
virtual void setData(int ID) {
/* Old default implementation */
std::cout << "Foo::setData int" << std::endl;
}
// New interface
virtual void setData(const dataObj& aObj) {
/* New default implementation */
std::cout << "Foo::setData dataObj" << std::endl;
setData(aObj.getID());
}
};
class A : public Foo
{
public:
virtual void setData(int ID) {
/* Old default implementation */
std::cout << "A:: setData int" << std::endl;
}
};
class B : public Foo
{
public:
virtual void setData(const dataObj& aObj) {
/* Old default implementation */
std::cout << "B:: setData dataObj" << std::endl;
}
};
int main(int argc, char* argv[])
{
A a;
B b;
dataObj d;
Foo* pa, * pb;
pa = &a;
pb = &b;
pa->setData(d);
pb->setData(d);
return 0;
}
Upvotes: 1
Reputation: 217398
You may do something like:
class Foo
{
public:
// Old interface
virtual void setData(int ID) { /* Old default implementation */ }
// New interface
virtual void setData(dataObj aObj) { /* New default implementation */ }
void init() {
if (useOldInterface()) {
setData(ID);
} else {
setData(aObj);
}
}
private:
// temporary method to be removed once all derived classes return false.
virtual bool useOldInterface() const { return true; }
};
And change progressively derived classes by adding
virtual bool useOldInterface() const override { return false; }
and appropriate void setData(dataObj aObj)
.
Upvotes: 2