Russian Qt Forum
Ноябрь 26, 2024, 10:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Приведение типов  (Прочитано 18434 раз)
goer
Гость
« Ответ #15 : Май 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
Гость
« Ответ #16 : Май 21, 2007, 14:42 »

Цитата: "Tonal"
Цитата: "kitov"
Для классов унаследованныx от QObject я бы предпочел
qobject_cast - быстрее ( ибо без rtti)
Есть реальные цифры?
На основании чего делается вывод, о тормознутости dynamic_cast по сравнению с qobject_cast


Какие тебе цифры надо ?
Напиши сам тест и замерь.
Всем исвестно что использование rtti
программу шустрее не делает.
Записан
goer
Гость
« Ответ #17 : Май 21, 2007, 15:02 »

Да, узкое место в rtti это сравнение строк, если троли пошли не таким прямым путем, следует ожидать большей скорости.

Вобще мне тоже было бы интересно посмотреть на результаты тестов. Подмигивающий
Записан
Tonal
Гость
« Ответ #18 : Май 22, 2007, 07:51 »

Открываем любой moc_*.cpp файл и внимательно рассматриваем функцию ClassName::qt_metacast(const char *_clname).
Сравнение строк и рекурсивные вызовы:
Код:

static const char qt_meta_stringdata_frmNotation[] = {
  "frmNotation\0"
};

void *frmNotation::qt_metacast(const char *_clname)
{
  if (!_clname) return 0;
  if (!strcmp(_clname, qt_meta_stringdata_frmNotation))
    return static_cast<void*>(const_cast< frmNotation*>(this));
  if (!strcmp(_clname, "Ui::frmNotation"))
    return static_cast< Ui::frmNotation*>(const_cast< frmNotation*>(this));
  return QDialog::qt_metacast(_clname);
}

Тут заметна ещё и потенциальная грабля с динамической линковкой при одноимённых классах в разных dll-ках.
Хотя эта задачку в рамках С++ автоматом пока не решается.

Про RTTI vs moc - компилятор знает всю иерархию класса, а moc - только непосредственных предков. Соответственно, умный компилятор, может сгенерировать довольно быструю функцию каста, чего moc не может в принципе.
Правда я не уверен, что какой-нибудь из компиляторов это делает. ;-)

Ну а тесты пусть делает тот, кто любит голословные утверждения на основе "общеизвестных фактов". ;-)
Записан
goer
Гость
« Ответ #19 : Май 22, 2007, 09:27 »

Продуктивно поспорили. Одни говорят что черное чернее белого потому что это черное, а другие что белое белее черного потому что это белое Подмигивающий

Цитировать
Ну а тесты пусть делает тот, кто любит голословные утверждения на основе "общеизвестных фактов".


Тесты вобще то делаются для проверки какой либо гипотезы или предположения и делают их как раз не словоблудники, а люди стремящиеся к обоснованности своих слов, чего и всем желаю.
Записан
Waryable
Гость
« Ответ #20 : Октябрь 12, 2009, 05:05 »

Всем привет. Что бы не создавать тему-дубликат пишу здесь, тем более, что вопрос 100% подходит данной теме.
Вобщем, есть проблема: имеется набор классов-наследников от QObject. Эти классы категорически желательно пихнуть в контейнер. Я так подозреваю проблема решается через касты. Как говорится, я с "детства" не люблю приведение типов, и максимум на что решался - это приведение базовых типов. А вот теперь мне похоже никуда не деца.
Очень приветствуются не конкретные решения, а некие наставнические советы + ссылки на подробные материалы по кастам. Пошарил в нете, что-то не нашел подходящего материала. А хочется разобраться изнутри как это происходит.

Немного уточняющей информации по классам, которые необходимо пихнуть в контейнер:
1. Классы имеют практически идентичный интерфейс(интерфейсные функции практически на 100% совпадают по названию и аргументам)
2. ... однако эти ф-ии выполняют свою работу различными методами(т.к. работа идет на уровне драйверов устройств)
3. Исходя из 2 и по некоторым другим соображениям требуется сделать максимально независимые классы.

И, всетаки, может кто производил спортивные соревнования на скорость м/у средствами Qt и С++?

ПС: Просьба сильно палками не бить.  Строит глазки
Записан
Waryable
Гость
« Ответ #21 : Октябрь 12, 2009, 06:47 »

Пока не нашел нормального источника информации попробовал примерчик:

Код
C++ (Qt)
class myClass1   {}
class myClass2   {}
...
class myClassN   {}
 
 
myClass1* myCl1 = new myClass1;
myClass2* myCl2 = new myClass2;
...
myClassN* myClN = new myClassN;
 
QList<QObject*> myObjList;
 
myObjList.append(myCl1);
myObjList.append(myCl2);
...
myObjList.append(myClN);
 
myClass1* fromListCl = qobject_cast<myClass1*>(myObjList.at(0));
Дальнейшая работа с указателем fromListCl вроде бы корректна. Вызываю методы, изменяю данные. Но ведь не всегда видать сразу все грабли, на то они и грабли.
« Последнее редактирование: Октябрь 12, 2009, 08:58 от Waryable » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #22 : Октябрь 12, 2009, 08:19 »

А точно нужно в:
Цитировать
myClass1* fromListCl = qobject_cast<myClass1*>(myObjList.at(1));

нужно myObjList.at(1) Непонимающий Может надо  myObjList.at(0) ? Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Waryable
Гость
« Ответ #23 : Октябрь 12, 2009, 08:57 »

А точно нужно в:
Цитировать
myClass1* fromListCl = qobject_cast<myClass1*>(myObjList.at(1));

нужно myObjList.at(1) Непонимающий Может надо   myObjList.at(0) ? Улыбающийся
Пардон, виноват не я, а копипаст зараза  Веселый
Исправил.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #24 : Октябрь 12, 2009, 11:14 »

Так в чем собственно вопрос\проблема?
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Октябрь 12, 2009, 19:05 »

Я тоже проблемы не разглядел. Ну сделали MyBaseClass, у него virtual'ы, потом породили MyClass1, MyClass2 и.т.п, для них переопределили virtual'ы. Указатели поместили в контейнер и работаете типа

container[index]->MyVitualFunc(..);

Ну когда-то может придется тип узнать но с нормальным набором virtual'ов - редко.
« Последнее редактирование: Октябрь 12, 2009, 19:19 от Igors » Записан
Waryable
Гость
« Ответ #26 : Октябрь 14, 2009, 04:59 »

Спс всем кто отозвался.
Igors, я думал над этим вариантом. Но почему-то интуитивно его отбросил, наверное я был не прав. А поступил так из соображений эффективности, т.е. посчитал что приведение указателя в типу будет быстрее, чем неявный анализ информации о типе объекта. Но чуть въехав в тему я понял, что для приведения к типу необходимо производить свой анализ.
Так в чем собственно вопрос\проблема?
Ну вопроса было два:
1. насколько быстро производится приведение к типу.
2. надежность способа, который я привел выше.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #27 : Октябрь 14, 2009, 11:14 »

А поступил так из соображений эффективности, т.е. посчитал что приведение указателя в типу будет быстрее, чем неявный анализ информации о типе объекта.
Не бывает просто "быстро/медленно" всегда что-то меряется по отношению к чему-то. Например, Вы собираетесь использовать QList. Операции с ним быстрые (если говорить "вообще") но намного медленнее чем приведение типов. Отказ от виртуальных методов не выигрывает в скорости если все равно находить тип вручную. 

Если Вам надо принципиально повысить скорость (выжать максимум) то надо обходиться без QObject, котейнеров и.т.п. то есть брать все это на себя. А на типах много не сэкономить Улыбающийся Но такая "супер-скорость" нужна очень редко (и кропотливая работа с ней должна быть оплачена Улыбающийся)

Если есть какие-то сомнения в скорости приведения - возьмите это на себя. Псевдокод

Код:
class MyBaseTypedObject : public QObject {
  ...
  virtual int GetTypeId( void  ) const = 0;
};

Чтобы использовать switch вместо неприятной последовательности qobject_case

Код:
switch (obj->GetTypeId()) {
  case OBJ_TYPE_1:
    ((MyObj1 *) obj)->DoSomething();
    break;
   ...
}
Пусть оно сильно не поможет но "сердце успокоится" Улыбающийся
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.123 секунд. Запросов: 23.