Здравствуйте, Erop, Вы писали:
F>>Для чуть более длинной иерархии наследования Как раз в случае "дедушки"
E>А зачем это всё? Для реализации какой идеомы7 При решении какой задачи?
Не всё можно уложить в стандартные паттерны и идиомы. Мне несколько раз доводилось строить такую архитектуру, в основном в случае изменияющихся условий и требований к проекту.
E>Почему дальний потомок вообще отличается от левого класса по уровню необходимого доступа?
? не соввсем понял вопрос. Может, ты имел в виду предка, а не потомка? Ну так это всё-таки "родственник", а не просто приятель — как и в жизни, родню часто выбирать не приходится
Курица — это инструмент, с помощью которого одно яйцо производит другие.
E>>А зачем это всё? Для реализации какой идеомы? При решении какой задачи?
F>Не всё можно уложить в стандартные паттерны и идиомы. Мне несколько раз доводилось строить такую архитектуру, в основном в случае изменияющихся условий и требований к проекту.
Выделенное наводит на мысль, что на самом деле был нужен рефакторинг, а не protected наследование...
Не мог бы ты пояснить, причины, по которым такая странная конструкция понадобилась, и чем они отличались от причин использовать friend...
F>? не соввсем понял вопрос. Может, ты имел в виду предка, а не потомка? Ну так это всё-таки "родственник", а не просто приятель — как и в жизни, родню часто выбирать не приходится
Ну у меня есть какая-то иерархия, при этом корень этой иерархии выведен из чего-то protected образом.
При этом надо это не непосредственно корню, а дедушкам.
Не совсем понятно чем дедушки отличаются от всего остального кода.
Без примера хотя бы и умозрительного, но мотивированного, я продолжу считать это всё просто кривизной дизайна...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>>>А зачем это всё? Для реализации какой идеомы? При решении какой задачи? F>>Не всё можно уложить в стандартные паттерны и идиомы. Мне несколько раз доводилось строить такую архитектуру, в основном в случае изменияющихся условий и требований к проекту.
E>Выделенное наводит на мысль, что на самом деле был нужен рефакторинг, а не protected наследование... E>Не мог бы ты пояснить, причины, по которым такая странная конструкция понадобилась, и чем они отличались от причин использовать friend...
Ну как бывает, приходит кто-то и говорит, хочу такое же, но "с перламутровыми пуговицами", т.е. поведение, отличающееся от исходного не сильно. Проще отнаследоваться от потомка, чем перекраивать довольно сложную иерархию, рефакторинг — это же не цель, а средство, к тому же довольно дорогостоещее.
F>>? не соввсем понял вопрос. Может, ты имел в виду предка, а не потомка? Ну так это всё-таки "родственник", а не просто приятель — как и в жизни, родню часто выбирать не приходится
E>Ну у меня есть какая-то иерархия, при этом корень этой иерархии выведен из чего-то protected образом. E>При этом надо это не непосредственно корню, а дедушкам. E>Не совсем понятно чем дедушки отличаются от всего остального кода.
Не, это надо не дедушке, а потомкам. Дедушка обычно всё равно не создаётся сам по себе, и его методы тоже не public, а protected.
E>Без примера хотя бы и умозрительного, но мотивированного, я продолжу считать это всё просто кривизной дизайна...
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[7]: А их надо уничтожать, пока они маленькие... :)
Здравствуйте, frogkiller, Вы писали:
F>Ну как бывает, приходит кто-то и говорит, хочу такое же, но "с перламутровыми пуговицами", т.е. поведение, отличающееся от исходного не сильно. Проще отнаследоваться от потомка, чем перекраивать довольно сложную иерархию, рефакторинг — это же не цель, а средство, к тому же довольно дорогостоещее.
Ну в том и искусство, чтобы вовремя решиться на рефакторинг, пока контроль над кодом ещё не утрачен
F>Не, это надо не дедушке, а потомкам. Дедушка обычно всё равно не создаётся сам по себе, и его методы тоже не public, а protected.
Ну так и пример будет? Правда очень интересно
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
W>class I
W>{
W>};
W>class A : public I
W>{
W>};
W>class B : protected A
W>{
W>};
W>B b;
W>I& ri = b; // error C2243: 'type cast' : conversion from 'B *__w64 ' to 'I &' exists, but is inaccessible
W>
W>Как можно, не открывая реализацию A, допустить преобразование к I? Даже operator I&(), определенный в B не хочет работать. Конечно, можно сделать отдельный метод для преобразования, но это не совсем выход. W>Заранее спасибо.
Я думаю, так заработает
class B: protected
{
...
I & getI() { return static_cast<I&>(*this); }
...
}
Сам не проверял
Re[8]: А их надо уничтожать, пока они маленькие... :)
Здравствуйте, Erop, Вы писали:
E>Ну в том и искусство, чтобы вовремя решиться на рефакторинг, пока контроль над кодом ещё не утрачен
Угу, ключевое слово здесь — вовремя.
F>>Не, это надо не дедушке, а потомкам. Дедушка обычно всё равно не создаётся сам по себе, и его методы тоже не public, а protected. E>Ну так и пример будет? Правда очень интересно
Ну, например, так. Жила-была маленькая велосипедная библиотечка, используемая в несколкьких небольших программах — и в ней некоторое количество классов, реализующих протоколы обмена данными. По историческим причинам таких протоколов было два, отличались они не очень сильно, но изжить какой-нибудь один и оставить, соответственно, другой — не получалось. Реализованы они были по всем правилам: с вынесением общей функциональности в базовый класс, относледованный приватно. И вдруг, спустя длительное время нарисовался ещё один протокол, придуманный совсем другими товарищами, который потребовалось поддерживать — он был как две капли воды похож на один из имеющихся, отличался совсем уж в мелочах, но чтобы реализовать их нужен был доступ к функциональности и базового класса и потомка. Что сделали: лёгким движением руки поменяли классу доступ наследования на protected (изменение, которое на 99.9999% не поломает текущие программы) и отнаследовались публично от этого класса, заменив две функции (вместо 10-15, которые пришлось бы копировать, если бы оставили двухуровневую иерархию) и один typedef. Возможно, стоило бы провести более детальный рефакторинг, но какой-то необходимости в нём не видел — пересечений со вторым исходным протоколом практически не было, и возможный выигрыш не окупал трудозатрат на изменение кода в нескольких местах, проверки работы получившихся программ, а самое главное на их приёмку крупным заказчиком.
Разумеется, все персонажи вымышленны, а совпадения случайны
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[9]: А их надо уничтожать, пока они маленькие... :)
Здравствуйте, frogkiller, Вы писали:
F>Реализованы они были по всем правилам: с вынесением общей функциональности в базовый класс, относледованный приватно.
А почему так, а не через агрегацию? Типа как бы просто два класса, а общая часть -- в поле каждого из них?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: А их надо уничтожать, пока они маленькие... :)
Здравствуйте, Erop, Вы писали:
F>>Реализованы они были по всем правилам: с вынесением общей функциональности в базовый класс, относледованный приватно. E>А почему так, а не через агрегацию? Типа как бы просто два класса, а общая часть -- в поле каждого из них?
Из-за большой любви к абстракции В общей части было несколько pure virtual функций, которым оперировала логика, находящаяся в этой же общей части. Чтобы достичь такого же эффекта с агрегированием, потребовалось бы протаскивать в этот общий член указатель/ссылку на контейнер, но такое применение callback'ов мне кажется довольно ущербным. Или вообще можно было применять какой-нибудь visitor — но в случае с небольшим числом потомков это представлялось как "из пушки по воробьям".
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[5]: Открыть дедушку
От:
Аноним
Дата:
22.01.09 10:00
Оценка:
Здравствуйте, Went, Вы писали: А>>Иначе имеем веселый прикладной эффект: добавление еще одного класса-наследника разваливает половину кода, QA в мыле, манагеры в панике. W>А тут просто over9000 пафоса и никакой конкретики.