Название: qpolymorphic_downcast Отправлено: Akon от Сентября 08, 2010, 22:04 Аналог boost::polymorphic_downcast<>() для QObject типов. Над boost::polymorphic_downcast<>() имеет те же преимущества/недостатки, что и qobject_cast<>() над dynamic_cast<>() (см. Ассистант).
Код: /// Convenient type conversions under QObject classes with RTTI-independent qobject_cast<>(). Название: Re: qpolymorphic_downcast Отправлено: Авварон от Сентября 08, 2010, 22:44 а чем не угодил сам куобжект каст?
Название: Re: qpolymorphic_downcast Отправлено: lit-uriy от Сентября 08, 2010, 23:42 вроде как применяться должно так:
Код
Хотя внутренности говорят, что написать можно было и так: Код что явно короче. Тогда в чём выгода? Название: Re: qpolymorphic_downcast Отправлено: navrocky от Сентября 08, 2010, 23:45 а чем не угодил сам куобжект каст? Насколько я понял, нет оверхеда в релизе, а при отладке работает проверка на корректность. Хотя пользоваться надо с осторожностью..Название: Re: qpolymorphic_downcast Отправлено: Rcus от Сентября 09, 2010, 05:20 Похоже не я один такой (http://www.prog.org.ru/index.php?topic=12932.msg83293#msg83293). Правда в текущей версии я слегка модифицировал код:
Код
Название: Re: qpolymorphic_downcast Отправлено: Akon от Сентября 09, 2010, 10:32 вроде как применяться должно так: Код
Хотя внутренности говорят, что написать можно было и так: Код что явно короче. Тогда в чём выгода? Из boost: The C++ built-in static_cast can be used for efficiently downcasting pointers to polymorphic objects, but provides no error detection for the case where the pointer being cast actually points to the wrong derived class. The polymorphic_downcast template retains the efficiency of static_cast for non-debug compilations, but for debug compilations adds safety via an assert() that a dynamic_cast succeeds. The C++ built-in dynamic_cast can be used for downcasts and crosscasts of pointers to polymorphic objects, but error notification in the form of a returned value of 0 is inconvenient to test, or worse yet, easy to forget to test. The throwing form of dynamic_cast, which works on references, can be used on pointers through the ugly expression &dynamic_cast<T&>(*p), which causes undefined behavior if p is 0. The polymorphic_cast template performs a dynamic_cast on a pointer, and throws an exception if the dynamic_cast returns 0. polymorphic_downcast example: #include <boost/cast.hpp> ... class Fruit { public: virtual ~Fruit(){}; ... }; class Banana : public Fruit { ... }; ... void f( Fruit * fruit ) { // ... logic which leads us to believe it is a Banana Banana * banana = boost::polymorphic_downcast<Banana*>(fruit); ... Описанное решение предлагает ту же семантику, но реализовано посредством не C++-шного dynamic_cast<>(), а Qt-шного qobject_cast<>(). Чем в данном случае qobject_cast<>() лучше/хуже dynamic_cast<>() см. Ассистант. Похоже не я один такой (http://www.prog.org.ru/index.php?topic=12932.msg83293#msg83293). Правда в текущей версии я слегка модифицировал код: Код
Твое решение более информативно в плане сообщений; ничего не имею против, но мне достаточно останова по ассерту с последующим восхождением по стеку в отладчике для локализации ошибки. Все равно эти сообщения не для пользователя, а для программиста. Код: T target_obj; Название: Re: qpolymorphic_downcast Отправлено: Rcus от Сентября 09, 2010, 11:21 Твое решение более информативно в плане сообщений; ничего не имею против, но мне достаточно останова по ассерту с последующим восхождением по стеку в отладчике для локализации ошибки. Все равно эти сообщения не для пользователя, а для программиста. У меня это тоже не для пользователя, только с 64M памяти отладчик не позапускаешь, да и корки писать некуда.Код: T target_obj; Название: Re: qpolymorphic_downcast Отправлено: Akon от Сентября 09, 2010, 13:22 Моя реализация повторяет по записи остальные касты - указатели к указателям. Временный объект не создается, а этот dummy-pointer нужен для обращения к staticMetaObject нужного класса, QObject::staticMetaObject - не вариант. Прошу прощения, я тут конкретно ошибся, потому как забыл, что аргументом шаблона будет указатель на тип а не сам тип. Соответственно: 1. Никакого временного объекта. 2. Вместо QObject::staticMetaObject конечно же нужно было T::staticMetaObject, но это не скомпилируется, т.к. T - указатель. Тут попрет boost::remove_pointer<T>::type::staticMetaObject.className(), но при наличии простого способа через dummy-pointer это выглядит извратом. |