crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Приведение типов C++/QT
fsMark
  опции профиля:
сообщение 9.8.2008, 11:22
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 97
Регистрация: 23.4.2008
Из: г. Киров
Пользователь №: 155

Спасибо сказали: 10 раз(а)




Репутация:   1  


Писал недавно одному знакомому о приведении типов в QT, решил выложить на форум вдруг комунибудь будет полезно или ктонибудь дополнит(сам пишу на QT 4 месяца :))
На мой взгляд картина выглядить слкдующим образом:

стандартная конструкция:
classA* A = new classA;
classB* B = (classB*)A;
приведет указатель на classA к указателю на classB, это стандартный способ приведения указателей унаследованный от языка C, при таком приведении не производиться никаких проверок не на этапе компиляции не на этапе исполнения со всеми вытекающими последствиями.

В C++ введенны следующие более тонкие конструкции:

classA* A = new classA;
classB* B = static_cast<classB*>A;
Эта конструкция приведет указатель на classA к Указателю на classB при том условии что класс classB является наследдником класса classA

classA* A = new classA;
classB* B = dynamic_cast<classB*>A;
Эта конструкция действует аналогично static_cast, отличие заключается в том что производиться проверка на принадлежность обекта на который сыллается А класу В, для проверки использукется информатция о типах времени выполнения(RTTI) которая естественно должна быть включена на этапе компилятции(в болщенстве современных компиляторов включена по умолчанию).
Если проверка завершается неудачно то dynamic_cast вернет нулевой указатель.
В некоторых компиляторах dynamic_cast может не работать через границы разделяемых библиотек.

QT предоставляет свое средство для приведения указателей заместо dynamic_cast:
qobject_cast аналогичен dynamic_cast для подклассов QObject(для остальных классов результат не определен), но он не зависит от RTTI и может работать через границы разделяемых библиотек.

вот пример из ассистента:
QObject *obj = new QTimer; // QTimer inherits QObject
QTimer *timer = qobject_cast<QTimer *>(obj);
// timer == (QObject *)obj
QAbstractButton *button = qobject_cast<QAbstractButton *>(obj);
// button == 0

Кроме того для приведения указателей на классы унаследованные от QGraphicsItem(не наследник QObject) существует qgraphicsitem_cast.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 9.8.2008, 14:51
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Еще дополнить и можно будет оформить в статью. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
void*
  опции профиля:
сообщение 9.8.2008, 17:46
Сообщение #3


Программист-самоучка
***

Группа: Участник
Сообщений: 429
Регистрация: 4.6.2008
Пользователь №: 193

Спасибо сказали: 28 раз(а)




Репутация:   3  


из Qt-шных, еще существуют такие касты:
qdbus_cast, qscriptvalue_cast, qstyleoption_cast и qvariant_cast.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 10.8.2008, 14:51
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Для того, чтобы работал qobject_cast, нужно не только унаследоваться от QObject, но и добавить макрос Q_OBJECT в описание класса. Для остальных Qt-шных кастов тоже требуются некоторые телодвижения. В отличие от dynamic_cast для которого всё делается автоматом при наличии хотя бы одного виртуального метода. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
fsMark
  опции профиля:
сообщение 10.8.2008, 22:16
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 97
Регистрация: 23.4.2008
Из: г. Киров
Пользователь №: 155

Спасибо сказали: 10 раз(а)




Репутация:   1  


Если не добавлять макрос Q_OBJECT то особого смысла наследоваться от QObject нет, теряются все вкусности... типа сигналов и слотов.
Непонял какие телодвижения ты имеешь в виду, если можешь опиши подробней.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 11.8.2008, 7:36
Сообщение #6


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Тем не менее, наследник QObject без Q_OBJECT вполне жизненная ситуация - например рабочий поток.

Про дополнительные телодвижения, нужно для каждого каста смотреть по месту. Например для qgraphicsitem_cast нужно переопределить virtual int QGraphicsItem::type () const так, чтобы он возвращал уникальное для всех использующихся в программе и плагинах наследников QGraphicsItem число.
Для остальных - копай ассистента.

Динамические касты для своей работы требуют дополнительную информацию связанную с экземпляром. В случае qobject_cast эту информацию добавляет moc, в случае qgraphicsitem_cast она достаётся из виртуальной функции, куда её явно положил разработчик. Для dynamic_cast компилятор автоматически связывает эту инфу с таблицей виртуальных методов.

Плюсы dynamic_cast в том, что он автоматом работает а любыми полиморфными объектами языка и в том, что компилятор может его заменить на static_cast в некоторых случаях (приведение наследника к базе).
Плюсы q*_cast в возможно меньшем объёме бинарика, и корректной работе на старых компиляторах.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuler
  опции профиля:
сообщение 1.10.2008, 11:15
Сообщение #7


Танцор диско
***

Группа: Участник
Сообщений: 441
Регистрация: 11.9.2008
Из: Москва
Пользователь №: 289

Спасибо сказали: 6 раз(а)




Репутация:   -1  


про static_cast и dynamic_cast написано не шибко правильно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
fsMark
  опции профиля:
сообщение 1.10.2008, 11:27
Сообщение #8


Студент
*

Группа: Участник
Сообщений: 97
Регистрация: 23.4.2008
Из: г. Киров
Пользователь №: 155

Спасибо сказали: 10 раз(а)




Репутация:   1  


Цитата(kuler @ 1.10.2008, 12:15) *
про static_cast и dynamic_cast написано не шибко правильно


Ждем спаведливой критики :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuler
  опции профиля:
сообщение 1.10.2008, 11:44
Сообщение #9


Танцор диско
***

Группа: Участник
Сообщений: 441
Регистрация: 11.9.2008
Из: Москва
Пользователь №: 289

Спасибо сказали: 6 раз(а)




Репутация:   -1  


Цитата(fsMark @ 1.10.2008, 12:27) *
Цитата(kuler @ 1.10.2008, 12:15) *
про static_cast и dynamic_cast написано не шибко правильно


Ждем спаведливой критики :)

вломы писать, там много, труп страуса почитайте
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 1.10.2008, 11:57
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(kuler @ 1.10.2008, 12:44) *
вломы писать, там много, труп страуса почитайте

Тогда нефиг хаять! Вообще, за такого рода посты я бы забанил. Что за ерунда? Вполне достоверная информация была приведена. Если она неполная, то можно дополнить, а не хаять!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 21.10.2021, 8:28