C++: переопределить наследование классов?

В библиотеке, которую я использую, есть два класса, позвольте называть их 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 21.08.2018 21:04

@ scohe001 возможно. Мне нужно будет изучить это подробнее, чтобы увидеть, будет ли это проблемой. Я предполагаю, что в худшем случае я просто создаю подкласс class B и повторно реализую то, что я добавил в подкласс класса A. Однако вопрос был в том, есть ли способ «переопределить» наследование - скажем, заменить ваш предка класса A на мой класс A, что позволит избежать подобных проблем.

ibrewster 21.08.2018 21:09

Эмм ... не могли бы вы просто расширить класс B вместо класса A?

3Dave 21.08.2018 21:15

XY проблема? Почему вы хотите добавить функциональность к классам, которые вам не нужны (я полагаю, они находятся в библиотеке)?

SergeyA 21.08.2018 21:16

@ 3Dave Разумное предложение, за исключением случаев, когда я использую класс A (или его подкласс) напрямую. Класс B изменяет поведение класса A способами, которые иногда, но не всегда, желательны.

ibrewster 21.08.2018 21:18

@SergeyA Потому что базовые классы (которые, да, находятся в библиотеке) не работают довольно так, как я хочу, особенно в этом случае в отношении блокировок файлов.

ibrewster 21.08.2018 21:20

Это может быть очевидно, но в вашем переопределении вы можете указать, какую версию переопределенного метода вы хотите вызвать. classA::foo() и др.

3Dave 21.08.2018 21:28

Вы не можете модифицировать ни A, ни B. Затем используйте новый класс C, который НЕ наследуется от A, B, но содержит в качестве члена экземпляр B. Необходимые дополнения могут работать с этим объектом (используйте его методы).

Ripi2 21.08.2018 21:34

Похоже, вам нужна композиция вместо наследования.

Hatted Rooster 21.08.2018 21:36

@ Ripi2 Похоже, ваше предложение может быть лучшим вариантом. Спасибо :)

ibrewster 21.08.2018 22:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
11
111
1

Ответы 1

template<class T /* T must be derived from A */> class myclsssA:T { /* ... */ }

new myclassA<B>()

Иногда это срабатывает, в зависимости от того, что вы делаете. Существует крайняя точность в том, что это может делать или не делать, и в вопросе просто недостаточно деталей, чтобы даже приблизиться к знанию.

Это делает myclassA наиболее производной формой, поэтому она может успешно переопределять все виртуальные методы. Но если вы не создадите экземпляры B, это вообще не поможет.

См. Мой edit2 для более конкретного примера. Сработает ли это в таком случае? Если да, то как?

ibrewster 21.08.2018 21:38

@ibrewster: Обратите внимание, как это работает только в том случае, если вы контролируете создание B (или, в данном случае, квадрата).

Joshua 21.08.2018 21:39

Да, у меня есть полный контроль над созданием экземпляров классов, я не могу контролировать только определения.

ibrewster 21.08.2018 21:41
template <class T:A> не компилируется ... Вы имели в виду =?
HolyBlackCat 21.08.2018 21:42

@HolyBlackCat: После еще двух неудачных попыток найти синтаксис я удалил фильтр типов.

Joshua 21.08.2018 21:45

Другие вопросы по теме