В библиотеке, которую я использую, есть два класса, позвольте называть их class A и class B, чтобы сохранить общие черты. Class B наследуется от class A, поэтому что-то вроде:
class A{
...
}
class B: public A{
...
}
Так что ничего особенного, но я не могу редактировать ни один из этих классов напрямую. Теперь я хотел добавить некоторые функции к классу A, поэтому я делю его на подкласс, скажем, myClassA, и добавляю функциональность в этот подкласс. Это отлично работает, когда я использую myClassA, но, конечно, везде, где я использую, classB по-прежнему наследуется от оригинального class A, а не от myClassA.
Как я могу создать подкласс class B, унаследованный от myClassA вместо исходного classA? Будет ли работать подкласс, унаследованный от ОБЕИХ class B и myClassA, даже если class B уже унаследован от исходного class A?
Обновлено: Я только что попробовал вариант «Наследовать от ОБА» и могу подтвердить, что он работает с нет, по крайней мере, без гораздо большей работы. Наверное, в комментариях упоминалась проблема бриллиантов. Так что, если нет способа наследования class Bотвергатьclass A с myClassA, мне, возможно, придется просто повторно реализовать изменения, которые я внес в свой подкласс class A в подклассе class B, хотя это было бы нарушением принципа DRY. .
Обновлено еще раз: Чтобы сделать это немного более конкретным, возьмите, например, стандартный пример класса «shape». Итак, в этом случае у вас будет базовый класс, скажем, rectangle, а rectangle, в свою очередь, наследуется классом square. Теперь я хочу добавить функциональность, скажем, функцию «перемещения», которая сдвигает положение объекта на указанную величину. Это было бы одинаково как для rectangle, так и для square, поэтому в идеале я бы реализовал его в классе rectangle, и square унаследовал бы его. Однако, поскольку у меня нет прямого доступа к классам rectangle или square, я могу работать только с подклассами. Таким образом, я хочу создать подкласс square, который наследуется от подкласса мойrectangle, а не от базового класса rectangle.
РЕДАКТИРОВАТЬ 3: чтобы переформулировать и прояснить вопрос с точки зрения более конкретного примера: «Могу ли я / как я могу создать подкласс square, но унаследовать его от my_rectange (подкласс rectangle) ВМЕСТО наследования от rectangle?» Или, говоря другими словами: «Могу ли я / как я могу заменить базовый класс на что-то свое, если я не могу изменить класс напрямую?»
Возможный дубликат Как виртуальное наследование решает «ромбовидную» (множественное наследование) неоднозначность?
@ scohe001 возможно. Мне нужно будет изучить это подробнее, чтобы увидеть, будет ли это проблемой. Я предполагаю, что в худшем случае я просто создаю подкласс class B и повторно реализую то, что я добавил в подкласс класса A. Однако вопрос был в том, есть ли способ «переопределить» наследование - скажем, заменить ваш предка класса A на мой класс A, что позволит избежать подобных проблем.
Эмм ... не могли бы вы просто расширить класс B вместо класса A?
XY проблема? Почему вы хотите добавить функциональность к классам, которые вам не нужны (я полагаю, они находятся в библиотеке)?
@ 3Dave Разумное предложение, за исключением случаев, когда я использую класс A (или его подкласс) напрямую. Класс B изменяет поведение класса A способами, которые иногда, но не всегда, желательны.
@SergeyA Потому что базовые классы (которые, да, находятся в библиотеке) не работают довольно так, как я хочу, особенно в этом случае в отношении блокировок файлов.
Это может быть очевидно, но в вашем переопределении вы можете указать, какую версию переопределенного метода вы хотите вызвать. classA::foo() и др.
Вы не можете модифицировать ни A, ни B. Затем используйте новый класс C, который НЕ наследуется от A, B, но содержит в качестве члена экземпляр B. Необходимые дополнения могут работать с этим объектом (используйте его методы).
Похоже, вам нужна композиция вместо наследования.
@ Ripi2 Похоже, ваше предложение может быть лучшим вариантом. Спасибо :)





template<class T /* T must be derived from A */> class myclsssA:T { /* ... */ }
new myclassA<B>()
Иногда это срабатывает, в зависимости от того, что вы делаете. Существует крайняя точность в том, что это может делать или не делать, и в вопросе просто недостаточно деталей, чтобы даже приблизиться к знанию.
Это делает myclassA наиболее производной формой, поэтому она может успешно переопределять все виртуальные методы. Но если вы не создадите экземпляры B, это вообще не поможет.
См. Мой edit2 для более конкретного примера. Сработает ли это в таком случае? Если да, то как?
@ibrewster: Обратите внимание, как это работает только в том случае, если вы контролируете создание B (или, в данном случае, квадрата).
Да, у меня есть полный контроль над созданием экземпляров классов, я не могу контролировать только определения.
template <class T:A> не компилируется ... Вы имели в виду =?
@HolyBlackCat: После еще двух неудачных попыток найти синтаксис я удалил фильтр типов.
Похоже, вы освежаете проблема с бриллиантами