| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Связь класса с определённой структурой данных |
| Автор: eXtremal7 3.9.2009, 10:44 | ||||||||
Предположим, есть набор объектов типа:
Задача состоит в том, чтобы была возможность доступа к определённой структуре данных(уникальной для A, B и C) во время выполнения. Для этого в базовый класс base можно добавить поле типа int index, создать массив структур, и получать нужную структуру по индексу. Однако при создании объектов A, B и C надо же как-то этот индекс определять то. Вот для этого и можно использовать список типов из библиотеки loki:
Тогда можно преобразовывать имя типа в индекс, но тогда как объявить массив структур, о котором говорилось выше? Разве что только так:
А конструкторы объектов будут выглядеть как-то так:
Решение вполне рабочее, но два момента совсем не нравится:
Явное указание типа объекта в конструкторе(indexOf<AllTypes, A>) |
| Автор: mes 3.9.2009, 11:01 |
| посмотрите паттерн визитор |
| Автор: eXtremal7 3.9.2009, 11:42 | ||
И как я смогу по указателю базового класса к ним добраться интересно? Была идея хранить непосредственно указатель на структуру в базовом классе вместо индекса.. тогда список типов не нужен:
но появляется ограничение - весь код с этими классами должен собираться как shared library(.dll/.so), в противном случае в каждом исполняемом модуле будет своя копия структур.. может быть так что объекты будут одинаковые, а значения value - разные, поэтому проверить принадлежность указателя base к производным классам простым сравнением value нельзя. А это что, можно подробнее ? |
| Автор: zim22 3.9.2009, 11:57 |
http://lmgtfy.com/?q=%D0%BF%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD+%D0%B2%D0%B8%D0%B7%D0%B8%D1%82%D0%BE%D1%80 |
| Автор: Lazin 3.9.2009, 12:43 | ||||
| поскольку StructType один и тот-же для A, B и С, то можно добавить виртуальный метод(защищенный), который будет возвращать указатель на эту структуру и вызываться он будет из базового класса, это очевидный вариант можно еще ввести класс - посредник, между классом А..С и базовым классом -
тут, шаблон BaseProxy, знает тип своего потомка, и может извлечь какие-либо специфичные для A данные, благодаря этому, не нужно вручную определять метод getStruct для каждого потомка
а как-бы тебе в этом помогли списки типов? Добавлено @ 12:44 кстати, твой первоначальный пример, как раз и является кривой эмуляцией вызова вирт. ф-ии, по сути, не по форме |
| Автор: Lazin 3.9.2009, 13:01 | ||||
в принципе, это можно сделать еще проще, и более обобщенно:
с помощью структуры proxy_all_access, можно не только ссылку на статический член класса - потомка возвращать, а вообще, делать с потомком все что душе угодно, для этого нужно добавить соотв. методы в структуру. еще один плюс, тому, кто реализует класс - потомок, достаточно написать friend proxy_all_access, вместо template<class T> friend ...; это лучше читается |
| Автор: eXtremal7 3.9.2009, 13:16 | ||||||
Почему же кривой то, разве прочитать индекс из объекта будет не быстрее чем вызов виртуальной функции ? А есть сравнить производительность dynamic_cast со сравнением индекса:
Списки типов нужны чтобы сопоставить индекс каждому типу, это удобнее чем enum отдельный объявлять для этого.
Если предполагается расширяемость, то это единственный путь, а вот если набор объектов жестко зафиксирован, почему бы и не оптимизировать доступ к структуре и проверку типов ? |
| Автор: Lazin 3.9.2009, 13:31 | ||||||
в любом случае, это преждевременная оптимизация, к тому-же очень сомнительная Добавлено через 4 минуты и 21 секунду
каждый программист, рано или поздно пытается написать свою "быструю" замену dynamic_cast? если правильно спроектировать программу,то dynamic_cast не нужен |
| Автор: eXtremal7 4.9.2009, 11:20 |
Далеко не всегда известен тип данных во время компиляции.. но если известен, то конечно dynamic_cast не нужен. А там где нужен обычно и делают свои ускоренные реализации. |
| Автор: mes 4.9.2009, 12:28 | ||
Lazin имел в виду, что dynamic_cast не используется не потому, что известен реальный тип объекта, а потому что есть другие способы реализации нужного взаимодействия с объектом, и они не есть ускоренные реализации dynamic_casta. |
| Автор: eXtremal7 7.9.2009, 13:39 | ||
А я говорю, что не всегда можно так организовать взаимодействие с объектом, что dynamic_cast будет не нужен, могу привести пару примеров: llvm.org и их набор шаблонов cast<>, dyn_cast<>, isa<>, ну а также Qt и их qobject_cast<> - всё это является ускоренными аналогами dynamic_cast-а и активно используется в этих проектах. |
| Автор: hente 7.9.2009, 14:30 |
| гы....задача таже самая тока под Linux. Кропотливое но элементарное решение как было сказано выше с помощью паттерна визитор. Реализовав раз достаточно легко переносится на другой проект...Где то год назад(даже не зная слова паттерн) сам придумывал мучился кое-как сделал, щас на это дело ушло пару часов, за одно и старую библиотеку переделал Вообще хочу сказать что паттерны милое дело если грамотно делать то переносимость 100%я (Win<->Linux, без Qt), а времени скока экономит так ваще молчу.... К стате советую книгу "Приемы объектно орентированного проектирования" Э.Гамма,Р.Хелм,Р.Джонсон,Д.Влиссилес. |