![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
mes, не, в этом случае например в объекте Cone будут не 2 поля с разными именами, а массив или вектор из 2х элементов типа Dimention, для ввода которых надо будет обойти этот массив итератором вызывая Input()
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Вы не про то.. я про Ваш субъект Radius. В вашей компоновке операция Input жестко привязана к нему. Разницы нет кто из чего состоит. Суть в том что к иерархии субъектов в таком случае нельзя добавить новую операцию, в отличии от подхода с визитором. (см. пример с кодом) Это сообщение отредактировал(а) mes - 20.3.2009, 13:31 |
|||
|
||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
накидал пример на скорую руку
суть в том, чтобы вместо иерархии объектов, использовать композицию, в данном случае я использовал boost::fusion для хранения структуры объекта. Примитивные типы для данного примера это point, line и metadata. Объект класса metadata хранит информацию о классе объекта. В принципе, можно добавить метаданные для каждого параметра, каждого объекта, для этого нужно вместо boost::fusion::vector использовать что-то вроде boost::fusison::map, но мне лень это делать) Добавлено через 3 минуты и 2 секунды в принципе, объект класса metadata в каждом новом объекте GenericBody это лишний оверхэд, достаточно создать один объект metadata на каждый "класс"(вариант инстанциирования GenericBody) и в GenericBody хранить только ссылку на такой глобальный объект Добавлено через 6 минут и 40 секунд примерно так:
|
||||
|
|||||
| GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
Lazin, выглядит страшно, а работает наверное еще страшнее,
с посетителем куда как лучше, и накладных расходов на память 0 к тому же то что у вас - несколько не соответствует задаче ТС, нужно хранить размеры а не координаты |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
а это и есть паттерн visitor мой пример можно обобщит хоть на хранение килограммов и амперов, смысл в том, что у нас есть набор параметров разных типов(в данном случае это координаты точек и длины), и из них мы строим еще больше классов(линии и окружности), каждый такой класс(GenericBody) имеет ссылку на описатель класса и набор параметров, набор параметров хранится в boost::fusion::vector, что эквивалентно использованию обычной структуры, так-что утверждение неверно Добавлено через 5 минут и 19 секунд по памяти это +4 байта на каждый объект GenericBody и еще +4 байта на указатель на таблицу вирт. функций, по сравнению с обычными структурами по скорости, это один вызов виртуальной ф-ии(в случае если visitor получает указатель на весь класс сразу), против N вызовов(N - количество параметров класса), разница будет незаметна... |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Lazin, Ваш пример хорош, когда Body является просто контейнером параметров. Однако фигура это не просто набор параметров..
к примеру, попробуйте в Вашем примере, применить операцию Draw () Это сообщение отредактировал(а) mes - 20.3.2009, 15:30 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
мой пример хорош, когда код должен хорошо масштабировться в сторону добавления новых классов, так-как все "методы"(объекты клaсса BodyAccessor) не нужно реализовывать для каждого класса. В принципе можно получить любую функциональность, но, если таких классов мало, то проще использовать стандартный подход.
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
согласен, но сказал бы так: его хорошо использовать наряду со стандартным подходом, в случае если предполагается также добавление новых классов (например посредством плагина). т.е условная иерархия такая : Line, Cirlce, Quad, Generic. Это сообщение отредактировал(а) mes - 20.3.2009, 15:39 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
я бы не сказал, тогда придется вручную реализовывать метод accept для всех вариантов: Line, Circle, Quad etc, в общем тогда проще использовать стандартный подход, и быдлокодить всю иерархию игнорируя тот факт, что объекты Line, Circle, Quad etc, состоят из небольшого набора элементов. Конечно мой пример далек от совершенства, его еще можно сильно улучшить. Но с точки зрения архитектуры, он лучше чем иерархия классов. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
покажите пример удобной реализации функции Draw() для Вашего примера, и если ее недостатки не перекроют достоинства Вашей модели, тогда я с Вами соглашусь. Это сообщение отредактировал(а) mes - 20.3.2009, 16:22 |
|||
|
||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
самый простой вариант, можно добавить вирт. ф-ю в класс Body, и специализировать ее для каждого шаблона, но, нужно писать ф-ю для каждой специализации, что плохо
Добавлено через 41 секунду но, можно это сделать и по другому) |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
прежде чем прокомментировать Ваш пример, хотелось бы также понять какой другой вариант Вы имеете ввиду. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
я думал не специализировать для каждого GenericBody ф-ю draw, а просто реализовать ее в виде отдельного объекта и передавать ее в GenericBody в качестве параметра шаблона, сейчас покажу...
Добавлено через 10 минут и 35 секунд примерно так...
теперь не обязательно реализовывать метод GenericBody::draw, функторы, занимающиеся отрисовкой фигур можно использовать повторно, либо написать обобщенную версию такого функтора |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
в принципе, так можно добавить любую операцию, зависящую от всех данных сразу, например преобразование координат, в то-же время, можно писать обобщенные версии ф-ий, которые работают не со всем объектом целиком, а с его частями, например сериализация, интроспекция. Что-бы написать, к примеру, ф-ю считающую количество вершин геом. фигуры, нужно написать всего один функтор.
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |