I have a design issue. I'd like to use a function implementation from a "sister" class when deriving from an abstract class if it is possible.
Problem
I have some "historic" code that adds a behavior to a base class using inheritance.
Old code
///////////////// Historic code ////////////////:
class IBase
{
int value;
virtual int method(){
return value;
};
}
class DerivedHist : IBase {
void otherMethod(){
return;
}
}
New code
After some modifications, I ended up specializing the IBase in 2 derived classes (Derived1 and Derived2), and changed the IBase class to an abstract class. The problem is that I'd like to add the DerivedHist class behavior to both classes, and I don't see how to do it in a good way.
///////////////////// New code //////////////////////////:
//this time IBase is an abstract class
class IBase
{
int value;
virtual int method() = 0;
}
class DerivedHist : IBase {
void otherMethod(){
return;
}
//I'd like to use Derived1's or Derived2's implementation
virtual int method(){
//???
}
}
class Derived1 : IBase {
virtual int method(){
return 2*value;
}
}
class Derived2 : IBase {
virtual int method(){
return 3*value;
}
}
I don't see exactly how to put back the DerivedHist class in place...
Solutions
I came up with some ideas:
-
Write 2 classes equivalent to DerivedHist that inherit from Derived1 (say Derived1Hist) and from Derived2 (say Derived2Hist), but that means having two classes with almost the same code.
IBase / \ Derived1 Derived2 / \ Derived1Hist Derived2Hist
-
Using something like this in the DerivedHist constructor:
DerivedHist(IBase* other) : IBase(*other){ ... }
and call it with a dynamic cast:
Derived1 derived1(...); DerivedHist derivedHist(dynamic_cast<IBase*>(derived1));
Wouldn't this use the correct implementation of method() ? As we can call dynamic_cast(new Derived1(...))->method() I imagined that passing something like this in a copy constructor could work. I couldn't find a way to have the code compiling with something like this...
-
Have one of the Derived[1,2] object as a member
class DerivedHist : IBase { IBase methodHolder; DerivedHist(IBase other) : methodHolder(other){ ... } void otherMethod(){ return; } virtual int method(){ //here I'd have to copy the relevant data members to the other object methodHolder.value = value; //and then call the other method return methodHolder.method(); } }
This looks like the best solution of the 3.
But here the problem that I see is that I have not the data synced from DerivedHist and its methodHolder member.
I could keep track of every changes and apply it to methodHolder but this does not seem to be the perfect solution.
Summary
To summarize, the two main questions I have are the following:
- Is there a way to call an implementation of method() from another derived class ?
- Otherwise, what kind of pattern should I use to solve this issue ?
Aucun commentaire:
Enregistrer un commentaire