У меня проблема с дизайном. Я хотел бы использовать реализацию функции из "сестринского" класса при наследовании от абстрактного класса, если это возможно.
Проблема
У меня есть некоторый код «history c», который добавляет поведение к базовому классу с использованием наследования.
Старый код
///////////////// Historic code ////////////////:
class IBase
{
int value;
virtual int method(){
return value;
};
}
class DerivedHist : IBase {
void otherMethod(){
return;
}
}
Новый код
После некоторых изменений я закончил специализацию IBase в 2 производных классах ( Derived1 и Derived2) и изменили класс IBase на абстрактный класс. Проблема в том, что я хотел бы добавить поведение класса DerivedHist к обоим классам, и я не понимаю, как это сделать правильно.
///////////////////// 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;
}
}
Я не понимаю, как именно верните класс DerivedHist на место ...
Решения
Я придумал несколько идей:
Напишите 2 класса, эквивалентные DerivedHist, которые наследуют из Derived1 (скажем, Derived1Hist) и из Derived2 (скажем, Derived2Hist), но это означает наличие двух классов с почти одинаковым кодом.
IBase
/ \
Derived1 Derived2
/ \
Derived1Hist Derived2Hist
Использование чего-то вроде этого в конструкторе DerivedHist:
DerivedHist(IBase* other) : IBase(*other){
...
}
и вызовите его с помощью динамического c cast:
Derived1 derived1(...);
DerivedHist derivedHist(dynamic_cast<IBase*>(derived1));
Разве при этом не использовалась бы правильная реализация метода ()? Поскольку мы можем вызвать dynamic_cast (new Derived1 (...)) -> method (), я представил, что передача чего-то подобного в конструкторе копирования может сработать. Мне не удалось найти способ компиляции кода с чем-то вроде этого ...
Сделать один из объектов Derived [1,2] членом
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();
}
}
Это похоже на лучшее решение для 3.
Но здесь проблема, которую я вижу, заключается в том, что у меня нет данных, синхронизированных из DerivedHist и его члена methodHolder.
Я мог бы отслеживать все изменения и применять его к methodHolder, но это не кажется идеальным решением.
Резюме
Подводя итог, у меня есть два основных вопроса: следующее:
- Есть ли способ вызвать реализацию метода () из другого производного класса?
- В противном случае, какой шаблон мне следует использовать для решения этой проблемы?