Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> (type) vs reinterpret_cast<type>, явное приведение в Си и Си++ 
V
    Опции темы
borisbn
Дата 16.9.2010, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Предисловие:
Иногда необходимо производить явное преобразование типа. Я понимаю, что это, скорее всего, из-за неправильной архитектуры, но ситуации бывают разные. Например, если используешь готовую функцию, как в QIODevice
Цитата
qint64 write ( const char * data, qint64 maxSize )

если у меня массив unsigned char x[1000], то я должен в явном виде преобразовать указатель на него к char*.
Я всегда ( по привычке, а не потому, что это правильно ) делаю преобразование в стиле Си
Код

write( ( char * ) x, ... 

Вопрос:
в чём существенное отличие такого преобразования от Си++-сного reinterpret_cast. И в чём отличие reinterpret_cast от static_cast.
Спасибо

Это сообщение отредактировал(а) borisbn - 16.9.2010, 10:08


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
proc_maker
Дата 16.9.2010, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 11.11.2006

Репутация: нет
Всего: 1



Привет.

Преобразование в стиле С приводит без проверки типов данных при условии что кастование таких типов впринципе возможно.

static_cast является почти аналогом сишного кастования но добавляет проверки типов:

Код

   char* a;
   static_cast<unsigned long>(a);                  // Не компилится
   (unsigned long)(a);                                     // компилится




>> И в чём отличие reinterpret_cast от static_cast.
reinterpret_cast применяется при кастовании поинтеров:

Код

   char* a;
   static_cast<unsigned long*>(a);               // Не компилится
   reinterpret_cast<unsigned long*>(a);       // Компилится

PM MAIL ICQ Skype   Вверх
boostcoder
Дата 16.9.2010, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  16.9.2010,  10:06 Найти цитируемый пост)
в чём существенное отличие такого преобразования от Си++-сного reinterpret_cast.

второй, умеет бросать исключение при невозможности каста.

Цитата(borisbn @  16.9.2010,  10:06 Найти цитируемый пост)
И в чём отличие reinterpret_cast от static_cast.

вот  smile

Добавлено через 44 секунды
вай, Алена фотку сменила.
PM WWW   Вверх
mrbrooks
Дата 16.9.2010, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 2
Всего: 306



borisbn, ко всему выше сказанному добавлю что reinterpret_cast аццкая вещь и использовать ее нужно осторожно. 
у нее были проблемы с выравниванием. 

Цитата(boostcoder @  16.9.2010,  11:31 Найти цитируемый пост)
вай, Алена фотку сменила. 

ололо. ну ты особо не увлекайся. рабочий день еще только начался.
PM MAIL   Вверх
azesmcar
Дата 16.9.2010, 10:37 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(borisbn @  16.9.2010,  10:06 Найти цитируемый пост)
в чём существенное отличие такого преобразования от Си++-сного reinterpret_cast

вообще рекомендуется использовать C++ style cast, но в данном случае сложно назвать какую-то существенную причину.

Цитата(borisbn @  16.9.2010,  10:06 Найти цитируемый пост)
И в чём отличие reinterpret_cast от static_cast.

reinterpret_cast не проверяет ничего, просто проводит cast. Какой угодно указатель к другому (какому угодно).
Код

struct X {};
struct Y {};

int main()
{
    X * xptr = 0;
    Y * yptr = reinterpret_cast<Y*>(xptr);
}


Цитата(borisbn @  16.9.2010,  10:06 Найти цитируемый пост)
И в чём отличие reinterpret_cast от static_cast.

static_cast проводит compile-time проверку, там, где это возможно например
Код

struct X {};
struct Y {};

int main()
{
    X * xptr = 0;
    Y * yptr = static_cast<Y*>(xptr); // ошибка
}

а вот в этом случае все будет работать
Код

struct X {};
struct Y : public X {};

int main()
{
    X * xptr = 0;
    Y * yptr = static_cast<Y*>(xptr); // ОК, преобразование возможно
}

иногда возникают ситуации, когда compile-time проверки недостаточно
Код

struct X {};
struct Y : public X {};
struct Z : public X {};

int main()
{
    X * xptr = new Z;
    static_cast<Y*>(xptr); // OK, cast прошел, хотя не должен был
}

тут можно использовать dynamic_cast, он проверяет runtime, при ошибке приведения возвращает NULL (если возвращает указатель) или генерирует исключение, если возвращает reference.

Добавлено через 37 секунд
Цитата(boostcoder @  16.9.2010,  10:31 Найти цитируемый пост)
второй, умеет бросать исключение при невозможности каста.

 smile это dynamic_cast, и то только тогда, когда делается cast к reference.

Добавлено через 1 минуту и 17 секунд
Цитата(proc_maker @  16.9.2010,  10:16 Найти цитируемый пост)
reinterpret_cast применяется при кастовании поинтеров:

а static_cast типа этого не умеет?
PM   Вверх
Dem_max
Дата 16.9.2010, 10:56 (ссылка)    | (голосов:6) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Цитата

если у меня массив unsigned char x[1000], то я должен в явном виде преобразовать указатель на него к char*.


глупости, даже преобразовывать не нужно, нужно только понимать чем unsigned char от char отличается в случает применения логических и орифметических операций


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
mes
Дата 16.9.2010, 11:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  16.9.2010,  09:37 Найти цитируемый пост)
reinterpret_cast не проверяет ничего, просто проводит cast. Какой угодно указатель к другому (какому угодно).

и даже это ? :
Код

  reinterpret_cast<void *> (&C::fn);


Цитата(azesmcar @  16.9.2010,  09:37 Найти цитируемый пост)
static_cast проводит compile-time проверку, там, где это возможно например

разочарую вас, но reinterpret_cast тоже проверяет возможность преобразования, но по своим правилам в отличии от static_cast.

главное отличие в том, что reeinterpret осуществляет "прямое" преобразование, а static, учитывая правила преобразования ( стандартные либо пользовательские для соотв. типов).



Цитата(Dem_max @  16.9.2010,  09:56 Найти цитируемый пост)
даже преобразовывать не нужно, 

может стоит проверить ? 
smile


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 16.9.2010, 11:47 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  16.9.2010,  11:40 Найти цитируемый пост)
и даже это ? :

нет, это уж слишком даже для reinterpret_cast, эти указатели размером не совместимы.

Цитата(mes @  16.9.2010,  11:40 Найти цитируемый пост)
разочарую вас, но reinterpret_cast тоже проверяет возможность преобразования, но по своим правилам в отличии от static_cast.

имелась ввиду проверка по иерархии классов (показано на примере). reinterpret_cast этого не делает.


Это сообщение отредактировал(а) azesmcar - 16.9.2010, 11:56
PM   Вверх
mes
Дата 16.9.2010, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  16.9.2010,  10:47 Найти цитируемый пост)
имелась ввиду проверка по иерархии классов

интересно, что подразумевается под словом "проверка" ?

Это сообщение отредактировал(а) mes - 16.9.2010, 11:56


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 16.9.2010, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  16.9.2010,  11:55 Найти цитируемый пост)
интересно, что подразумевается под словом "проверка" 

проверка можно ли совершать данное преобразование.

Цитата(mes @  16.9.2010,  11:40 Найти цитируемый пост)
и даже это ? :

по поводу этого, не уверен, но мне кажется это все же implementation defined.
PM   Вверх
Abyx
Дата 16.9.2010, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Цитата(azesmcar @  16.9.2010,  12:47 Найти цитируемый пост)
эти указатели размером не совместимы.

откуда вы знаете?
в ряде случаев в винде они будут совместимы.

PM MAIL   Вверх
azesmcar
Дата 16.9.2010, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Abyx @  16.9.2010,  12:02 Найти цитируемый пост)
откуда вы знаете?
в ряде случаев в винде они будут совместимы.

Не всегда. И если в каком-то компиляторе их размер равен это не значит, что они совместимы. я уже кажется писал
Цитата(azesmcar @  16.9.2010,  11:58 Найти цитируемый пост)
по поводу этого, не уверен, но мне кажется это все же implementation defined. 



Это сообщение отредактировал(а) azesmcar - 16.9.2010, 12:07
PM   Вверх
mes
Дата 16.9.2010, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  16.9.2010,  10:58 Найти цитируемый пост)
проверка можно ли совершать данное преобразование.

тогда следующий вопрос: есть класс B некий наследник класса А, соответсвенно преобразование возможно. Раз проверка прошла, то результат будет всегда ли  одинаков в обоих случаях ?
Код

B b;
static_cast<A&>(b); // 1
reinterpret_cast<A&>(b); // 2

smile



--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 16.9.2010, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  16.9.2010,  12:06 Найти цитируемый пост)
тогда следующий вопрос: есть класс B некий наследник класса А, соответсвенно преобразование возможно. Раз проверка прошла, то результат будет всегда ли  одинаков в обоих случаях ?

Нет, не всегда. reinterpret_cast игнорирует vtable pointer.

Добавлено через 39 секунд
хотя я не совсем понял каким образом этот вопрос связан с темой проверки возможности преобразования?

PM   Вверх
Abyx
Дата 16.9.2010, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



azesmcar, нет, размер указателя на член класса зависит еще и от ОС и назначения этого члена класса.
в ряде случаев ОС будет гарантировать что указатель на член класса будет обычным указателем
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0636 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.