Название: Приведение типов Отправлено: pakulo от Май 13, 2007, 20:32 Какая разница между
QWidget *widget = qobject_cast<QWidget *>(objectSender); и QWidget *widget = (QWidget *)(objectSender); Название: Приведение типов Отправлено: Alex Forth от Май 13, 2007, 20:50 Первый использует метаобьектную ситему Qt и возвратит 0, если преобразование невозможно, а второй просто позволяет преобразовать что-то размером в 4 байта(на х86) к типу QWidget *.
Название: Приведение типов Отправлено: pakulo от Май 13, 2007, 21:58 Первым способом я могу преобразовать если создал свой виджет?
добавлено спустя 31 минуту: у меня есть клас class MyLabel: public QLabel { } делаю MyLabel *lb; QLabel *label = qobject_cast<QLabel *>(lb); как мне получить 0? Название: Приведение типов Отправлено: Lion от Май 13, 2007, 22:18 Если Mylasbel не наследник QLabel, то получишь ноль.
Название: Приведение типов Отправлено: pakulo от Май 13, 2007, 22:41 Ну это понятно... меня интересует как получить 0 если он наследник, см. мой пример...
Название: Приведение типов Отправлено: QCasper от Май 13, 2007, 23:06 Цитата: "pakulo" Ну это понятно... меня интересует как получить 0 если он наследник, см. мой пример... Если lb == 0 то и label тоже будет 0. Название: Приведение типов Отправлено: Racheengel от Май 13, 2007, 23:33 MyLabel *lb;
QLabel *label = !(qobject_cast<QLabel *>(lb)); ? Название: Приведение типов Отправлено: pakulo от Май 13, 2007, 23:44 Просто вот такая проблема
у меня есть два обьекта MyLabel *lb; QLabel *label; в функцию передается QObject * и мне в функции нужно проверить если это MyLabel сделать то-то, если QLabel те-то... Название: Приведение типов Отправлено: pastor от Май 13, 2007, 23:55 Цитата: "pakulo" Просто вот такая проблема у меня есть два обьекта MyLabel *lb; QLabel *label; в функцию передается QObject * и мне в функции нужно проверить если это MyLabel сделать то-то, если QLabel те-то... Можно заюзать например такое: Код: ... Название: Приведение типов Отправлено: Tonal от Май 14, 2007, 08:29 Цитата: "pakulo" Просто вот такая проблема у меня есть два обьекта MyLabel *lb; QLabel *label; в функцию передается QObject * и мне в функции нужно проверить если это MyLabel сделать то-то, если QLabel те-то... Именно для таких случаев в С++ существует dynamic_cast. Он работает для классов у которых есть хотя бы одна виртуальная функция и только при включенном rtti. В Qt ты можешь воспользоваться qobject_cast - это то же самое, что и стандартный dynamic_cast, но можно не включать rtti - Qt его эмулирует самостоятельно. qobject_cast работает только для наследников QObject, и макрос Q_OBJECT должен быть. Иначе никто не гарантирует, что он вернёт. ;-) P.S. Я предпочитаю использовать dynamic_cast как более универсальное средство. ;-) Название: Приведение типов Отправлено: Racheengel от Май 14, 2007, 08:44 Тогда наверно так:
MyLabel *lb; QLabel *label = dynamic_cast<MyLabel *>(lb); label будет = 0, если lb не объект класса MyLabel. Название: Приведение типов Отправлено: vregess от Май 19, 2007, 11:45 Информацию об объекте типа получают с помощью оператора typeid (нужно прицепить заголовок <typeinfo>).
Код:
Здесь возвращается ссылка на объект типа type_info, который описывает тип объекта _MY_OBJECT_ Вторая форма: Код:
Ну тут понятно - type_info описывает тип ИМЯ_ТИПА. Эту форму можно использовать в инструкциях сравнения типов. (QWidget *)(objectSender) - это в Си. В С++ нужно использовать (по стандарту) различные *_cast. Цитата: "pakulo" Просто вот такая проблема у меня есть два обьекта MyLabel *lb; QLabel *label; в функцию передается QObject * и мне в функции нужно проверить если это MyLabel сделать то-то, если QLabel те-то... Код:
Сам не проверял, но должно работать). Вроде так. Если я ошибаюсь, было бы интересно услышать - где. Название: Приведение типов Отправлено: SABROG от Май 19, 2007, 12:13 А еще можно зарегистрировать свой MetaType:
Код:
Название: Приведение типов Отправлено: kitov от Май 19, 2007, 13:00 Цитата: "Tonal" Цитата: "pakulo" Просто вот такая проблема у меня есть два обьекта MyLabel *lb; QLabel *label; в функцию передается QObject * и мне в функции нужно проверить если это MyLabel сделать то-то, если QLabel те-то... Именно для таких случаев в С++ существует dynamic_cast. Он работает для классов у которых есть хотя бы одна виртуальная функция и только при включенном rtti. В Qt ты можешь воспользоваться qobject_cast - это то же самое, что и стандартный dynamic_cast, но можно не включать rtti - Qt его эмулирует самостоятельно. qobject_cast работает только для наследников QObject, и макрос Q_OBJECT должен быть. Иначе никто не гарантирует, что он вернёт. ;-) P.S. Я предпочитаю использовать dynamic_cast как более универсальное средство. ;-) Для классов унаследованныx от QObject я бы предпочел qobject_cast - быстрее ( ибо без rtti) Название: Приведение типов Отправлено: Tonal от Май 21, 2007, 10:10 Цитата: "kitov" Для классов унаследованныx от QObject я бы предпочел Есть реальные цифры?qobject_cast - быстрее ( ибо без rtti) На основании чего делается вывод, о тормознутости dynamic_cast по сравнению с qobject_cast Название: Приведение типов Отправлено: goer от Май 21, 2007, 11:29 Assitant:
Цитировать The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries. qobject_cast() can also be used in conjunction with interfaces; Поскольку qobject_cast работает только для QObject-ов было бы глупо невоспользовоться этим ограничением для оптимизации кастинга ;) Название: Приведение типов Отправлено: kitov от Май 21, 2007, 14:42 Цитата: "Tonal" Цитата: "kitov" Для классов унаследованныx от QObject я бы предпочел Есть реальные цифры?qobject_cast - быстрее ( ибо без rtti) На основании чего делается вывод, о тормознутости dynamic_cast по сравнению с qobject_cast Какие тебе цифры надо ? Напиши сам тест и замерь. Всем исвестно что использование rtti программу шустрее не делает. Название: Приведение типов Отправлено: goer от Май 21, 2007, 15:02 Да, узкое место в rtti это сравнение строк, если троли пошли не таким прямым путем, следует ожидать большей скорости.
Вобще мне тоже было бы интересно посмотреть на результаты тестов. ;) Название: Приведение типов Отправлено: Tonal от Май 22, 2007, 07:51 Открываем любой moc_*.cpp файл и внимательно рассматриваем функцию ClassName::qt_metacast(const char *_clname).
Сравнение строк и рекурсивные вызовы: Код:
Тут заметна ещё и потенциальная грабля с динамической линковкой при одноимённых классах в разных dll-ках. Хотя эта задачку в рамках С++ автоматом пока не решается. Про RTTI vs moc - компилятор знает всю иерархию класса, а moc - только непосредственных предков. Соответственно, умный компилятор, может сгенерировать довольно быструю функцию каста, чего moc не может в принципе. Правда я не уверен, что какой-нибудь из компиляторов это делает. ;-) Ну а тесты пусть делает тот, кто любит голословные утверждения на основе "общеизвестных фактов". ;-) Название: Приведение типов Отправлено: goer от Май 22, 2007, 09:27 Продуктивно поспорили. Одни говорят что черное чернее белого потому что это черное, а другие что белое белее черного потому что это белое ;)
Цитировать Ну а тесты пусть делает тот, кто любит голословные утверждения на основе "общеизвестных фактов". Тесты вобще то делаются для проверки какой либо гипотезы или предположения и делают их как раз не словоблудники, а люди стремящиеся к обоснованности своих слов, чего и всем желаю. Название: Re: Приведение типов Отправлено: Waryable от Октябрь 12, 2009, 05:05 Всем привет. Что бы не создавать тему-дубликат пишу здесь, тем более, что вопрос 100% подходит данной теме.
Вобщем, есть проблема: имеется набор классов-наследников от QObject. Эти классы категорически желательно пихнуть в контейнер. Я так подозреваю проблема решается через касты. Как говорится, я с "детства" не люблю приведение типов, и максимум на что решался - это приведение базовых типов. А вот теперь мне похоже никуда не деца. Очень приветствуются не конкретные решения, а некие наставнические советы + ссылки на подробные материалы по кастам. Пошарил в нете, что-то не нашел подходящего материала. А хочется разобраться изнутри как это происходит. Немного уточняющей информации по классам, которые необходимо пихнуть в контейнер: 1. Классы имеют практически идентичный интерфейс(интерфейсные функции практически на 100% совпадают по названию и аргументам) 2. ... однако эти ф-ии выполняют свою работу различными методами(т.к. работа идет на уровне драйверов устройств) 3. Исходя из 2 и по некоторым другим соображениям требуется сделать максимально независимые классы. И, всетаки, может кто производил спортивные соревнования на скорость м/у средствами Qt и С++? ПС: Просьба сильно палками не бить. ::) Название: Re: Приведение типов Отправлено: Waryable от Октябрь 12, 2009, 06:47 Пока не нашел нормального источника информации попробовал примерчик:
Код Дальнейшая работа с указателем fromListCl вроде бы корректна. Вызываю методы, изменяю данные. Но ведь не всегда видать сразу все грабли, на то они и грабли. Название: Re: Приведение типов Отправлено: kuzulis от Октябрь 12, 2009, 08:19 А точно нужно в:
Цитировать myClass1* fromListCl = qobject_cast<myClass1*>(myObjList.at(1)); нужно myObjList.at(1) ??? Может надо myObjList.at(0) ? :) Название: Re: Приведение типов Отправлено: Waryable от Октябрь 12, 2009, 08:57 А точно нужно в: Пардон, виноват не я, а копипаст зараза :DЦитировать myClass1* fromListCl = qobject_cast<myClass1*>(myObjList.at(1)); нужно myObjList.at(1) ??? Может надо myObjList.at(0) ? :) Исправил. Название: Re: Приведение типов Отправлено: pastor от Октябрь 12, 2009, 11:14 Так в чем собственно вопрос\проблема?
Название: Re: Приведение типов Отправлено: Igors от Октябрь 12, 2009, 19:05 Я тоже проблемы не разглядел. Ну сделали MyBaseClass, у него virtual'ы, потом породили MyClass1, MyClass2 и.т.п, для них переопределили virtual'ы. Указатели поместили в контейнер и работаете типа
container[index]->MyVitualFunc(..); Ну когда-то может придется тип узнать но с нормальным набором virtual'ов - редко. Название: Re: Приведение типов Отправлено: Waryable от Октябрь 14, 2009, 04:59 Спс всем кто отозвался.
Igors, я думал над этим вариантом. Но почему-то интуитивно его отбросил, наверное я был не прав. А поступил так из соображений эффективности, т.е. посчитал что приведение указателя в типу будет быстрее, чем неявный анализ информации о типе объекта. Но чуть въехав в тему я понял, что для приведения к типу необходимо производить свой анализ. Так в чем собственно вопрос\проблема? Ну вопроса было два:1. насколько быстро производится приведение к типу. 2. надежность способа, который я привел выше. Название: Re: Приведение типов Отправлено: Igors от Октябрь 14, 2009, 11:14 А поступил так из соображений эффективности, т.е. посчитал что приведение указателя в типу будет быстрее, чем неявный анализ информации о типе объекта. Не бывает просто "быстро/медленно" всегда что-то меряется по отношению к чему-то. Например, Вы собираетесь использовать QList. Операции с ним быстрые (если говорить "вообще") но намного медленнее чем приведение типов. Отказ от виртуальных методов не выигрывает в скорости если все равно находить тип вручную. Если Вам надо принципиально повысить скорость (выжать максимум) то надо обходиться без QObject, котейнеров и.т.п. то есть брать все это на себя. А на типах много не сэкономить :) Но такая "супер-скорость" нужна очень редко (и кропотливая работа с ней должна быть оплачена :)) Если есть какие-то сомнения в скорости приведения - возьмите это на себя. Псевдокод Код: class MyBaseTypedObject : public QObject { Чтобы использовать switch вместо неприятной последовательности qobject_case Код: switch (obj->GetTypeId()) { |