Учитывая устаревший код, система имеет следующую иерархию классов:
Base
^
|
----------+---------------
^ ^ ^ ^ ^
| | | | |
A1 B1 C1 D1 E1
^ ^ ^ ^ ^
| | | | |
A2 B2 C2 D2 E2
.......
^ ^ ^ ^ ^
| | | | |
An Bn Cn Dn En
Иерархия представляет сообщения в некотором конкретном домене.
Базовый класс - это, конечно, базовый класс всех сообщений.A1..E1 - это сообщения, принадлежащие версии 1 домена, A2..E2 - версии 2 и т. Д.Обратите внимание, что An должен наследоваться напрямую от An-1, поскольку An переопределяет определенные методы An-1.
Существует некоторая функциональность, общая для всех сообщений, поэтому она определяется как Base :: PerformFunctionality .Некоторая часть функциональности относится только к версии n , поэтому есть виртуальная функция Base :: SpecificPartOfFunctionality , которая вызывается Base :: PerformFunctionality .
Так что моя проблема в том, как переопределить Base :: SpecificPartOfFunctionality всеми An..En.
Я вижу 2 возможных решения, которые мне не очень нравятся:
Реализация Base :: SpecificPartOfFunctionality в каждом и каждом An..En.
Проблема с этим решением состоит в том, что реализация должна быть точно такие же для каждого класса, поэтому я просто повторяю код.
Дополнительная проблема состоит в том, что, если вводится новый класс Fn, разработчик может забыть реализовать SpecificPartOfFunctionality .
Ввести BaseN класс, производный от Base, в то время как каждый An..En также является производным от BaseN :
class BaseN : public Base {
//...
SpecificPartOfFunctionality() { ...}
};
class An: public An-1, public BaseN { .. }
Проблема с этим решением состоит в том, что оно создает проблему diamond .
Дополнительная проблема заключается в том, что произойдет, если какой-либо другой версии m потребуется переопределить Base :: SpecificPartOfFunctionality .Следуя решению, мы введем BaseM , который переопределит Base :: SpecificPartOfFunctionality .Так что SpecificPartOfFunctionality будет вызываться для - из BaseN или BaseN .Это полный беспорядок.
Есть предложения?