Урок 56. Явное преобразование типов данных (операторы casts)

   ⁄ 

 Обновлено 27 Апр 2017

  ⁄   

В предыдущем уроке мы узнали, что компилятор иногда неявно преобразовывает значения из одного типа данных в другой. Когда вы хотите расширить значение из одного типа данных в более крупный похожий тип, то тогда неявное преобразование – хороший вариант.

Но многие начинающие программисты часто пытаются сделать что-то вроде этого: float x = 11 / 3;. Однако, поскольку 11 и 3 — это целые числа, то никакого расширения не происходит. Выполняется целочисленное деление 11 / 3, результатом которого будет значение 3, которое затем неявно преобразовывается в 3.0 и присваивается переменной x!

В случае, когда вы используете литералы (такие как 11 или 3), замена одного или обоих целочисленных литералов значением типа с плавающей запятой (11.0 или 3.0) приведет к конвертации обоих операндов в значения типа с плавающей запятой, и деление будет выполнено на основе типа с плавающей запятой.

Но что, если использовать переменные?

Значением переменной x будет 3. Как сообщить компилятору, что мы хотим использовать деление на основе типа с плавающей запятой вместо целочисленного? Ответ – использовать один из операторов преобразования типов данных (type casting или просто cast), чтобы указать компилятору осуществить явное преобразование. cast – это непосредственный (явный) запрос программиста выполнить преобразование типа данных.

Операторы явного преобразования типов данных

В C++ есть 5 различных типов cast: C-style cast, static_cast, const cast, dynamic cast и reinterpret cast.

В этом уроке мы рассмотрим C-style cast и static_cast. dynamic cast отменяется до тех пор, пока мы не рассмотрим указатели и наследование.

const cast и reinterpret cast следует избегать вообще, потому что они полезны только в редких случаях и могут причинить немало проблем, если их использовать неправильно.

Правило: Избегайте использования const cast и reinterpret cast, если у вас нет на то веской причины.

C-style cast

В программировании на языке C явное преобразование типов данных выполняется с помощью оператора () – внутри пишем тип, в который нужно конвертировать. Например:

В программе выше мы используем cast, чтобы сообщить компилятору преобразовать переменную i1 в тип float. Поскольку i1 уже будет типа float, то i2 затем автоматически преобразуется в тип float также и деление выполнится на основе типа с плавающей запятой!

C++ также позволяет использовать этот оператор:

C-style cast не проверяется компилятором во время компиляции, поэтому может быть неправильно использован, так как позволяет делать вещи, которые могут быть без смысла, например, конвертировать тип const или изменять типы данных, не учитывая их диапазоны (что приведет к переполнению).

Следовательно, C-style cast лучше избегать.

Правило: Не используйте C-style cast.

static_cast

В C++ есть еще один оператор явного преобразования типов данных и это static_cast. Ранее, в уроке о символьном типе данных мы уже использовали static_cast, чтобы конвертировать char в int и, используя std::cout, вывести не символ, а целое число:

static_cast лучше всего использовать для преобразования одного фундаментального типа данных в другой.

Основным преимуществом static_cast является проверка компилятором во время компиляции, что усложняет возможность возникновения непреднамеренных ошибок. static_cast также (специально) имеет меньшее влияние, чем C-style cast, поэтому вы не сможете случайно изменить const или сделать другие вещи, которые не намеревались делать.

Использование операторов явного преобразования в неявном преобразовании

Если вы будете выполнять небезопасные неявные преобразования типов данных – компилятор будет жаловаться. Например:

Конвертация int (4 байта) в char (1 байт) потенциально опасна — компилятор выдаст предупреждение. Чтобы сообщить ему, что вы намеренно делаете что-то, что потенциально опасно (но хотите сделать это в любом случае), используйте оператор static_cast:

В следующем случае компилятор будет жаловаться, что конвертация из double в int может привести к потере данных:

Чтобы сообщить компилятору, что мы сознательно хотим сделать это:

Итого

Явное преобразование типов данных следует избегать, если это вообще возможно, поскольку всякий раз, когда выполняется подобное изменение, есть вероятность возникновения непредвиденных проблем. Но очень часто случаются ситуации, когда этого не избежать. Поэтому в таких случаях лучше использовать static_cast вместо C-style cast.

Тест

В чем разница между явным и неявным преобразованием типов данных?

Ответ

Неявное преобразование происходит, когда компилятор ожидает значение одного типа, но получает значение другого типа.

Явное преобразование происходит, когда пользователь использует оператор явного преобразования для конвертации значения из одного типа данных в другой.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (9 оценок, среднее: 4,89 из 5)
Загрузка...
Поделиться в:
Подписаться на обновления:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *