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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Достоинства static_cast  (Прочитано 17112 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #15 : Сентябрь 19, 2012, 11:45 »

Попробуем подытожить чем лучше static_cast

- не позволяет (на этапе компиляции) привести типы которые не могут быть совместимы
- соблюдает константность

Хмм... пока больше ничего по существу не слышал Улыбающийся От себя добавлю

- исключает возможность перепутать с перекрытым оператором (напр char*)
- хорошо заметен в коде (по-моему главное)

Смущает однако почти полное отсутствие примеров, да и имеющиеся не очень убедительны
Код
C++ (Qt)
QWidget * w;
..
QLineEdit * e = static_cast <QLineEdit *> (w);
 
Сравнивая это с топорным (QLineEdit *) w, - там мы падаем с 9-го этажа, а тут с 7-го. Да, наши шансы на выживание повышаются, но так ли уж значительно?  Улыбающийся

По поводу "ах, потеряли константность - как низко мы пали!" и.т.п. Давайте я создам др тему? По константности есть что обсудить - и много, но мешать все в кучу нехорошо
Записан
lesav
Частый гость
***
Offline Offline

Сообщений: 235


qnx.org.ru


Просмотр профиля WWW
« Ответ #16 : Сентябрь 19, 2012, 12:16 »

Падая с этажа можно и парашют прихватить
Код
C++ (Qt)
QWidget * w;
QLineEdit * e = static_cast <QLineEdit *> (w);
if (e)
{
 // OK
}
 
Записан

lesav
Частый гость
***
Offline Offline

Сообщений: 235


qnx.org.ru


Просмотр профиля WWW
« Ответ #17 : Сентябрь 19, 2012, 12:29 »

Пардон, static_cast в таком случае бесполезен.
Условие срабатывает только с dynamic_cast
Записан

Bepec
Гость
« Ответ #18 : Сентябрь 19, 2012, 12:56 »

Помоему все касты - есть лишь:

1) заметность в коде
2) ясность чего хотел пишущий эту строку программист
3) в последнюю очередь это проверки Улыбающийся

PS для меня удобнее будет увидеть статик каст и понять, что могут поступить неверные данные, чем смотреть на одинаковые (QLineEdit *) Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Сентябрь 19, 2012, 13:18 »

Ну хорошо, а вот примерчик (видел у Вити которого что-то пока не видно - занят наверно)
Код
C++ (Qt)
double d;
float f;
,,,
d = static_cast <double> (f);
f = static_cast <float> (d);
 
Понятно "дело вкуса", но все же - уместно ли такое использование static_cast? Является ли оно "хорошим тоном" или так - понты?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #20 : Сентябрь 19, 2012, 13:30 »

Скорее тогда уже не "дело вкуса", а придерживание единого стиля. Что значит не так уж мало.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Akon
Гость
« Ответ #21 : Сентябрь 19, 2012, 13:54 »

Код:
QWidget * w;
..
QLineEdit * e = static_cast <QLineEdit *> (w);
В таких случаях нужно использовать boost::boost_polymorphic_dowcast или qpolymorphic_dowcast и падать только в дебаге.

Код:
d = static_cast <double> (f);
f = static_cast <float> (d);
ОК, придерживаясь стиля
Код:
int i = 0x11223344;
char c = static_cast<char>(i);
Ну а теперь я меняю char c на short c и обламывась со вторым байтом (если не пофиксю все присваивания в коде).
Записан
Bepec
Гость
« Ответ #22 : Сентябрь 19, 2012, 13:58 »

Тащить boost в Qt-шный проект это конечно же хорошо Улыбающийся
И да, вы обламываетесь потому, что так написали Улыбающийся
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #23 : Сентябрь 19, 2012, 13:59 »

Сравнивая это с топорным (QLineEdit *) w, - там мы падаем с 9-го этажа, а тут с 7-го.
Незначительно, но и стоит это нам только несколько дополнительных набранных символов. Проверки происходят на этапе компиляции, так что в производительности мы не потеряем (хотя и это не всегда критично).

Условие срабатывает только с dynamic_cast
С незанулённым указателем не сработает.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #24 : Сентябрь 19, 2012, 14:14 »

Скорее тогда уже не "дело вкуса", а придерживание единого стиля. Что значит не так уж мало.
То есть это правильно, хорошо? Тогда прошу показать как написать напр такой кусочек (максимально упрощенный) в хорошем стиле приведения

Код
C++ (Qt)
struct Matrix2x2 {
double m00, m01, m10, m11;
};
 
void Transform( const Matrix2x2 & m, float * ioX, float * ioY )
{
double x = *ioX;
double y = *ioX;
 
*ioX = x * m.m00 + y * m.m10;
*ioY = x * m.m10 + y * m.m11;
}
 
Записан
CuteBunny
Гость
« Ответ #25 : Сентябрь 19, 2012, 15:35 »

Ну хорошо, а вот примерчик (видел у Вити которого что-то пока не видно - занят наверно)
Код
C++ (Qt)
double d;
float f;
,,,
d = static_cast <double> (f);
f = static_cast <float> (d);
 
Понятно "дело вкуса", но все же - уместно ли такое использование static_cast? Является ли оно "хорошим тоном" или так - понты?

Мне кажется:
Код
C++ (Qt)
d = static_cast<double>(f);
 
бессмысленная запись, т.к. d = f - ничего страшного не будет и по стандарту написано, что float to double conversion is safe, float же меньше double и поэтому никаких потерей точностей не будет...
Код
C++ (Qt)
f = static_cast <float> (d);
 

здесь да дело вкуса, можно static_cast<float>, можно (float) - в принципе оно быстрее по написанию...
Записан
CuteBunny
Гость
« Ответ #26 : Сентябрь 19, 2012, 15:55 »

Скорее тогда уже не "дело вкуса", а придерживание единого стиля. Что значит не так уж мало.
То есть это правильно, хорошо? Тогда прошу показать как написать напр такой кусочек (максимально упрощенный) в хорошем стиле приведения

Код
C++ (Qt)
struct Matrix2x2 {
double m00, m01, m10, m11;
};
 
void Transform( const Matrix2x2 & m, float * ioX, float * ioY )
{
double x = *ioX;
double y = *ioX;
 
*ioX = x * m.m00 + y * m.m10;
*ioY = x * m.m10 + y * m.m11;
}
 


Думается мне это таким образом:

Если напишу так:

Код
C++ (Qt)
struct Matrix2x2 {
double m00, m01, m10, m11;
};
 
void Transform( const Matrix2x2 & m, float * ioX, float * ioY )
{
double x = *ioX;
double y = *ioX;
 //IMHO: there's no difference in this situation whether I'll write explicit conversion in c++ style or in c-style
 //however i know few about c language, so I'd prefer to do everything in c++ way rather than in c-way
*ioX = static_cast<float>(x * m.m00 + y * m.m10); //or in C-style (float)(x * m.m00 + y * m.m10)
*ioY = static_cast<float>(x * m.m10 + y * m.m11); //or in C-style (float)(x * m.m00 + y * m.m10)
}
 


значи я знаю, что у меня никогда не будет потерей точностей и говорю это компилятору, чтобы не сыпал варнинг... Хотя мне кажется тут на лицо, опасность, т.к. double'ы умножаются потом еще и складываются, когда-нибудь выстрел будет в ногу... поэтому если я не уверен, что (x * m.m00 + y * m.m10) и (x * m.m10 + y * m.m11) - поместится во float, я вообще не буду писать никаких приведениев ни в С++ стиле ни в Си, оставлю так, пусть компилятор говорит мне об потенциальной опасности в будущем...
Записан
V1KT0P
Гость
« Ответ #27 : Сентябрь 19, 2012, 20:53 »

Ну хорошо, а вот примерчик (видел у Вити которого что-то пока не видно - занят наверно)
Понятно "дело вкуса", но все же - уместно ли такое использование static_cast? Является ли оно "хорошим тоном" или так - понты?
Тут уже сказали основное. У меня привычка кастить примитивные типы появилась после того, как без каста код который вроде как должен нормально работать работал не так как надо(если очень интересно, то я могу попробовать порыться в старых исходниках и найти участок где отсутствие каста приводит к неправильному поведению). Также каст примитивных типов служит явным выделением участка кода к которому надо присмотреться, может там затаилась ошибка.
Также статик использую для явного приведения к базовому классу.
Динамик каст использую для привидения к наследнику, а также он спасает от ошибок(попытка привести к классу которым он не является).
Констант и реинтерпрет касты использую только в исключительных ситуациях, ибо если она появляется то ошибка в архитектуре и надо ее менять.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #28 : Сентябрь 19, 2012, 21:52 »

констант_каст я юзаю при работе со сторонними либами с плохим апи или для снятия конста с this в константных методах. Что одно, что другое бывает достаточно редко.
реинтерпрет_каст я юзаю для чтения сишных структур из блока данных.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Akon
Гость
« Ответ #29 : Сентябрь 19, 2012, 22:24 »

А вот такая конструкция присуща адептам const propagation (в коих числюсь и я):
Код:
class ControlUnit {
...
const QList<Terminal*>& terminals() { return terminals_; }
const QList<const Terminal*>& terminals() const
{
return reinterpret_cast<const QList<const Terminal*>&>(
const_cast<ControlUnit*>(this)->terminals());
}
}
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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