![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| eXtremal7 |
|
||||||||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 30.8.2009 Репутация: нет Всего: нет |
Предположим, есть набор объектов типа:
Задача состоит в том, чтобы была возможность доступа к определённой структуре данных(уникальной для A, B и C) во время выполнения. Для этого в базовый класс base можно добавить поле типа int index, создать массив структур, и получать нужную структуру по индексу. Однако при создании объектов A, B и C надо же как-то этот индекс определять то. Вот для этого и можно использовать список типов из библиотеки loki:
Тогда можно преобразовывать имя типа в индекс, но тогда как объявить массив структур, о котором говорилось выше? Разве что только так:
А конструкторы объектов будут выглядеть как-то так:
Решение вполне рабочее, но два момента совсем не нравится:
Явное указание типа объекта в конструкторе(indexOf<AllTypes, A>) |
||||||||
|
|||||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
посмотрите паттерн визитор
|
|||
|
||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
можно использовать специализацию классов вместо списков типов:
но, стоит задаться вопросом, зачем? ведь это:
|
||||
|
|||||
| eXtremal7 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 30.8.2009 Репутация: нет Всего: нет |
И как я смогу по указателю базового класса к ним добраться интересно? Была идея хранить непосредственно указатель на структуру в базовом классе вместо индекса.. тогда список типов не нужен:
но появляется ограничение - весь код с этими классами должен собираться как shared library(.dll/.so), в противном случае в каждом исполняемом модуле будет своя копия структур.. может быть так что объекты будут одинаковые, а значения value - разные, поэтому проверить принадлежность указателя base к производным классам простым сравнением value нельзя. А это что, можно подробнее ? |
|||
|
||||
| zim22 |
|
|||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 24 Всего: 69 |
||||
|
||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
поскольку StructType один и тот-же для A, B и С, то можно добавить виртуальный метод(защищенный), который будет возвращать указатель на эту структуру и вызываться он будет из базового класса, это очевидный вариант
можно еще ввести класс - посредник, между классом А..С и базовым классом -
тут, шаблон BaseProxy, знает тип своего потомка, и может извлечь какие-либо специфичные для A данные, благодаря этому, не нужно вручную определять метод getStruct для каждого потомка
а как-бы тебе в этом помогли списки типов? Добавлено @ 12:44 кстати, твой первоначальный пример, как раз и является кривой эмуляцией вызова вирт. ф-ии, по сути, не по форме Это сообщение отредактировал(а) Lazin - 3.9.2009, 12:46 |
||||
|
|||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
в принципе, это можно сделать еще проще, и более обобщенно:
с помощью структуры proxy_all_access, можно не только ссылку на статический член класса - потомка возвращать, а вообще, делать с потомком все что душе угодно, для этого нужно добавить соотв. методы в структуру. еще один плюс, тому, кто реализует класс - потомок, достаточно написать friend proxy_all_access, вместо template<class T> friend ...; это лучше читается |
|||
|
||||
| eXtremal7 |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 30.8.2009 Репутация: нет Всего: нет |
Почему же кривой то, разве прочитать индекс из объекта будет не быстрее чем вызов виртуальной функции ? А есть сравнить производительность dynamic_cast со сравнением индекса:
Списки типов нужны чтобы сопоставить индекс каждому типу, это удобнее чем enum отдельный объявлять для этого. Если предполагается расширяемость, то это единственный путь, а вот если набор объектов жестко зафиксирован, почему бы и не оптимизировать доступ к структуре и проверку типов ? |
||||
|
|||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
прочитать индекс из объекта не намного быстрее, чем получить адрес вирт. ф-ии из VMT объекта, разница в один уровень косвенности при обращении к данным в любом случае, это преждевременная оптимизация, к тому-же очень сомнительная Добавлено через 4 минуты и 21 секунду
каждый программист, рано или поздно пытается написать свою "быструю" замену dynamic_cast? если правильно спроектировать программу,то dynamic_cast не нужен |
||||
|
|||||
| eXtremal7 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 30.8.2009 Репутация: нет Всего: нет |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Lazin имел в виду, что dynamic_cast не используется не потому, что известен реальный тип объекта, а потому что есть другие способы реализации нужного взаимодействия с объектом, и они не есть ускоренные реализации dynamic_casta. |
|||
|
||||
| eXtremal7 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 30.8.2009 Репутация: нет Всего: нет |
А я говорю, что не всегда можно так организовать взаимодействие с объектом, что dynamic_cast будет не нужен, могу привести пару примеров: llvm.org и их набор шаблонов cast<>, dyn_cast<>, isa<>, ну а также Qt и их qobject_cast<> - всё это является ускоренными аналогами dynamic_cast-а и активно используется в этих проектах. |
|||
|
||||
| hente |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 20.3.2009 Где: Томск Репутация: нет Всего: нет |
гы....задача таже самая тока под Linux. Кропотливое но элементарное решение как было сказано выше с помощью паттерна визитор.
Реализовав раз достаточно легко переносится на другой проект...Где то год назад(даже не зная слова паттерн) сам придумывал мучился кое-как сделал, щас на это дело ушло пару часов, за одно и старую библиотеку переделал Вообще хочу сказать что паттерны милое дело если грамотно делать то переносимость 100%я (Win<->Linux, без Qt), а времени скока экономит так ваще молчу.... К стате советую книгу "Приемы объектно орентированного проектирования" Э.Гамма,Р.Хелм,Р.Джонсон,Д.Влиссилес. Это сообщение отредактировал(а) hente - 7.9.2009, 14:30 --------------------
долой быдло кодеров!!! |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |