7 / 7 / 1
Регистрация: 04.12.2009
Сообщений: 42
|
||||||
1 | ||||||
Как узнать, какого типа объект находится по указателю26.03.2012, 23:31. Показов 22092. Ответов 22
Метки нет (Все метки)
Есть массив указателей базового класса, нужно узнать какие типы этих объектов.
0
|
26.03.2012, 23:31 | |
Ответы с готовыми решениями:
22
Как определиться объект какого типа мы перетаскивали мышью? Как узнать находится ли объект в фокусе Как узнать что находится в переменной типа byte[] Forbids casting в dlsym - ISO C++ не поддерживает приведение типа указателя на функцию к указателю на объект |
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
|
26.03.2012, 23:34 | 2 |
смотрите описание к оператору dynamic_cast. позволяет кастить указатель на базу к указателю на производный класс с проверкой. если производный имеет нужный тип, то скастится, иначе оператор вернет нуль или кинет исключение при преобразовании ссылок.
1
|
27.03.2012, 01:50 | 3 | |||||
3
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
27.03.2012, 06:15 | 4 |
Полиморфизм нужен для того, чтобы игнорировать действительный тип объектов и работать только с базовым.
0
|
4 / 4 / 0
Регистрация: 06.01.2012
Сообщений: 117
|
|
12.11.2012, 10:01 | 5 |
Если не хочешь разбираться с кастами и полиморфизмом, то заведи переменную в базовом классе флаг и с помощью него можешь узнавать тип уазателя
1
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
|
||||||
12.11.2012, 12:19 | 6 | |||||
Тут нужна динамическая идентификация типов что-то такое:
Дополнительно смотреть: http://khpi-iip.mipk.kharkiv.e... lava12.pdf http://gcc.gnu.org/onlinedocs/... 2ch39.html http://www.cplusplus.com/refer... type_info/ Определить все данные, тип которых вводится из командной строки Определение введенного типа
0
|
1 / 1 / 1
Регистрация: 22.12.2013
Сообщений: 27
|
|
23.01.2015, 19:44 | 7 |
Deviaphan, вы давно программируете? Категорически с Вами не согласен. Полиморфизм нужен как для использования общих виртуальных функций, так и для уникальных для каждого потомка. То есть это абсолютно рядовая задача программирования делать коллекцию базовых объектов и в дальнейшем преобразовывать их в потомки для дальнейшей обработки.
Вот один из множества примеров, взятых из реальной жизни: у Вас есть коллекция графических примитивов в виде линий и дуг, основанных на одном общем родительском классе gElement. Попробуйте написать функцию, находящую точки пересечения двух произвольных элементов, принимающую в качестве аргументов ссылки на gElement (double[] Intersection(gElement el1, gElement el2), не прибегая к преобразованию базовых элементов к родительским типам. Добавлено через 23 минуты А по топику полностью согласен с DU - нужно использовать dinamic_cast. Ответ dqrest тоже хорош, можно завести переменную, перечисляющую родительские типы и указывающую явно в какой тип надо преобразовать, что увеличит скорость выполнения при увеличении количества наследников. В этом случае можно будет использовать static_cast или явное преобразование - это еще прирост скорости.
0
|
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
|
|
23.01.2015, 21:41 | 8 |
Двойная диспетчеризация.
А dynamic_cast'ы и прочие "завести переменную" нужны только неосиляторам которые не могут спроектировать систему типов.
0
|
73 / 69 / 38
Регистрация: 09.10.2012
Сообщений: 238
|
|
23.01.2015, 23:53 | 9 |
Можно пример кода увидеть? Не пойму как это решит вопрос ТС-а.
Или имелось в виду, что решать задачу "Есть массив указателей базового класса, нужно узнать какие типы этих объектов." саму по себе не имеет смысла?
0
|
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
|
|
24.01.2015, 14:09 | 10 |
Вопрос ТС'а это никак не решит. Я неудачно процитировал, это ответ на вопрос:
А ответ на вопрос ТС'а простой - не нужно знать типы этих объектов.
1
|
1 / 1 / 1
Регистрация: 22.12.2013
Сообщений: 27
|
|
20.02.2015, 16:20 | 11 |
Для двойной диспетчеризации нужно знать какого типа объекты взаимодействуют. Она также не будет работать с коллекцией объектов базового типа. Если вы считаете такие коллекции бессмыленными - это ваш личный подход. Возможно вы предпочитаете писать на чистом С. С точки зрения ООП такие коллекции полностью оправданы и позволяют реализовать многие возможности ООП. Возможно вы неправильно понимаете идеологию ООП.
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
20.02.2015, 16:57 | 12 |
Учитывая, что последняя запись от господина kravam датирована 2012 годом, то как минимум 3 года.
А учитывая общую подкованность господина Deviaphan, то можно смело предположить, что он и в 2012 уже был специалистом. --------------------------------------------------------------- А вот ваши ответы красноречиво намекают: вы не умеете ооп. 1. Язык си, со своей процедурной парадигмой не имеет никакого отношения к ответа господина Deviaphan. 2. Технология полиморфизм, на которой базируется оо-парадигма, была разработана, что бы реализовать идеому: "закрыт для изменений, открыт для расширений". Другими словами, полиморфизм для того и нужен, что бы избежать необходимости пасти фактические типы, и уйти от километровых свитч-кейсов, и армии ифов. 3. То, как вы предлагаете использовать полиморфизм на корню прибивает идеому, ради которой он и был создан. И прекрасно реализуется на тех же свитч-кейсах (имея при этом все их недостатки). Это дает основание предположить, что вы сами не понимаете ООП. Более того: именно к вам можно обратить ваш собственный тезис: С точки зрения ООП ваш юзкейс нарушает идеому "зарыт для изменений, открыт для расширений", и прекрасно реализуется на обычном процедурном си при помощи свит-кейсов, или конструкций из if/else, имея при этом все их недостатки. Возможно вы предпочитаете писать на чистом С. Возможно вы просто неправильно понимаете идеологию ООП. Но такие коллекции не оправданы с точки зрения ООП, и ломают на корню многие из его возможностей. Что-то подобное в оо-архитектуре красноречивый признак её ущербности.
1
|
1 / 1 / 1
Регистрация: 22.12.2013
Сообщений: 27
|
|
20.02.2015, 21:47 | 13 |
Согласен, принцип открытости-закрытости может нарушаться в абстрактных коллекциях.
С теоретической точки зрения да, если нам нужна динамическая типизация, то мы не соблюдаем этот принцип. Но программирование прежде всего имеет смысл с точки зрения практики. И не спроста язык предлагает нам инструменты динамической типизации вроде dinamic_cast и typeid. Можно обойтись и без таких коллекций, только это усложнит реализацию. Лучше рассмотреть на конкретной задаче: Есть 2 контура Contour, состоящих из последовательно соединенных линий Line: Element и дуг Arc: Element. Нам нужно найти точки пересечения этих контуров. Архитектурное решение с применением абстрактных коллекций: Перечисляем элементы первого контура, для каждого из них перечисляем все элементы второго контура и вызываем у них метод PointF pf = el1.Intersect(el2); В методе Intersect каждого типа пишем свич-кейсы. Нарушаем принцип открытости-закрытости (при добавлении новых типов примитивов придется дописывать свич-кейсы в каждом "братском" классе), но простота реализации и поддержки, а также скорость выполнения программы при большом количестве элементов (касты делаются быстро, по крайней мере на C#). Какую можете предложить альтернативу? (Естественно в приватных функциях контура должны сохраняться возможности вставки, удаления, инверсии элементов, и желательно доступа к элементу по индексу). Добавлено через 39 минут Архитектурное решение с применением абстрактных коллекций: Вызываем метод cont1.Intersect(cont2); Перечисляем элементы первого контура, приводим к производному типу. Для каждого из них перечисляем все элементы второго контура, приводим их и вызываем метод PointF pf = (line1/arc1).Intersect(line2/arc2); Все свич-кейсы пишутся в методе Contour.Intersect. При добавлении новых типов примитивов, нужно будет дописать свич кейсы только этого метода, а ранее написанный код примитивов останется без изменений. В такой реализации не нарушается принцип открытости-закрытости, но остается простота реализации и поддержки, а также скорость выполнения программы при большом количестве элементов (касты делаются быстро, по крайней мере на C#). А вот избавиться от динамической типизации вряд ли получится. Отказываться от абстрактной коллекции тоже смысла не вижу и не считаю это ущербным. В принципах ООП ничего нет про ущербность абстрактных коллекций=)
0
|
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
|
|
20.02.2015, 23:35 | 14 |
Лолшто? Ты похоже вообще не шаришь о чем идет речь. На вот, просветись что-ли, довольно приятная реализация мультиметодов на плюсах: https://github.com/jll63/yomm11
1
|
1 / 1 / 1
Регистрация: 22.12.2013
Сообщений: 27
|
|
21.02.2015, 00:39 | 16 |
Спасибо. Просвещусь на досуге. Как я понимаю, в обоих случаях реализация осуществляется с помощью шаблонов.
Возможно они и лучше по многим аспектам, я пока эти подходы не изучил. Я ищу подход не только для плюсов, но и для C#. Там это скорее всего будет нереализуемо.
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|||||||||||
21.02.2015, 01:03 | 17 | ||||||||||
Пускай для простоты будет не линия, а отрезок.
Нужно отталкиваться от "способа обобщения". Что у нас есть? Контур, который может состоять из линий, дуг, и может быть ещё чего нибудь придумаем. Что общего у отрезков и дуг? Если мы можем выделить общее у этих двух элементов, например: "отрезок - это примитив состоящий из 2х точек" "дуга - это примитив состоящий из И отрезков" Пойдем дальше в нашем обобщении: отрезок - это контейнер для двух точек Но если так, то совокупность отрезков можно представить в виде списка точек. А значит дуга - это контейнер из И точек. И по аналогии, контур - это так же контейнер из N точек. Итого: вся архитектура сводится всего к двум элементам: точка, и контейнер точек. Дуги, отрезки, квадраты, прямоугольники и прочее - это все опционально. Всего лишь методы "удобного и быстрого" построения типичных фигур:
поиска пересечений для фигур состоящих из И точек. Если не ошибаюсь, то в мире компьютерной графики принцип разбиения любых геометрических фигур на многоугольники называется "адаптивной деградацией". --------------------------------------------------------------------------------------------- Теперь предположим, что в силу специфики задачи мы не можем прибегнуть к адаптивной деградации Предположим, нам нужно делать весьма точные расчеты, и оперировать нужно именно окружностями и настоящими дугами, а вовсе не многоугольниками. (предположим, что так захотел заказчик, и баста! ) В этом случае становится очевидным, что сделать универсальный алгоритм пересечения не получится. И придется реализовать весь комплект уникальных алгоритмов пересечений. Что само по себе уже нарушает идею "закрыт для изменений, открыт для расширений". Требование к задаче "выполнять обработку по уникальным способом в зависимости от типов участников", уже противоречит идее полиморфизма. И с этим мы бессильны, что либо поделать. Мы можем лишь облегчить сопровождение такого подхода. Например, мы можем построить решение, которое частично может поспособствовать универсальности решения. Допустим, если линия не умеет пересекаться с окружностью (программисты ещё не успели доделать этот алгоритм, но уже сейчас нужно показать промежуточные результаты работы), то линия может попросить окружность "адаптивно деградироваться", и в итоге отработает универсальный алгоритм. Кроме того, вместо свитч-кейсов и армии ифов, мы можем задействовать более быстрый вариант выборки "кто-с-кем" основанный на полиморфизме. Что ко всему прочему позволит выполнять проверку типобезопасности времени компиляции. И этот фактор очень важен, поскольку избавляет нас от использования медленного динамик_каст, медленных свитч-кейсов, медленных ифов, упрощает расширение системы, и в конечном счете ошибки времени компиляции - это всегда лучше, чем ошибки рантайма. Ничайно позабыть что-то уже не получится. Я не буду вдаваться в подробности модели самого контейнера графических элементов. В контексте нашей беседы главное - продемонстрировать диспетчеризацию. Ниже представленный код - пример-иллюстрация одного из возможных решений: http://rextester.com/JAIUXZ12714
2
|
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
|
||||||
21.02.2015, 01:26 | 18 | |||||
Ну как вариант можно не городить велосипеды и заюзать boost::variant
2
|
1 / 1 / 1
Регистрация: 22.12.2013
Сообщений: 27
|
|
21.02.2015, 15:19 | 19 |
Спасибо hoggy, мне очень понравилась такая реализация. Волшебный указатель this при вызове виртуального метода Intersect сам уже посылает нужный тип в функцию, действительно очень удобно, и работает также и на шарпе. Можно назвать это автоматическим приведением типа объекта посредством виртуальной функции. Небольшой минус в интерфейсе - нужно заводить две публичные функции для одного действия.
А вообще такой подход наверное применим во многих случаях в моих задачах. Может и можно. Не пользовался бустом. Не рассмотрели важный момент, что нам еще важна последовательность элементов, и они должны храниться в коллекции. Полагаю, вряд ли можно сделать коллекцию из элементов variant<line, arc?
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||||||
21.02.2015, 15:57 | 20 | |||||
Напрасно.
Добавлено через 33 минуты Думаю, применив шаблонную магию, технически возможно реализовать фильдеперстовый мультиметод, который выполняя проверки времени компиляции позволит разрулить динамику без необходимости обязательно от чего то там наследоваться, и реализовывать какие то методы. Дизайн например мог бы выглядеть так:
зы: это лишь концепт-дизайн. Я ничего подобного ещё не делал. Однако, мои знания шаблонов с++ дают мне основание полагать, что подобный дизайн реален. Хотя работа не на один вечер.
0
|
21.02.2015, 15:57 | |
21.02.2015, 15:57 | |
Помогаю со студенческими работами здесь
20
Как узнать из какого окна и какого процесса пришло сообщение? Подсчитать, сколько файлов какого типа находится на логическом диске по выбору пользователя От какого типа каждый объект прямо или косвенно является производным в .Net? Можно ли узнать если объект находится на объекте? Как вернуть объект по указателю Как удалить объект класс из кучи по указателю? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |