Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VC_Lect.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
15 Мб
Скачать
☆

1.4.Явное преобразование типов

В данном подразделе использован материал из раздела 6.2.7 [3].

Явным преобразованием или приведением типа называют преобразование переменной, выражения и т.п. из одного типа в другой. В языке С такое преобразование применялось, например, в следующем виде:

void *p;

// …

char *s=(char *)p;

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

Для снижения вероятности совершения ошибок, связанных с приведением типа, в языке С++ введены следующие операции приведения типа:

  • dynamic_cast – для преобразования полиморфных типов;

  • static_cast – для преобразования неполиморфных типов;

  • const_cast –для удаления атрибутов const, volatile и __unaligned;

  • reinterpret_cast – для преобразования любого интегрального типа в указатель и наоборот;

  • safe_cast – используется на платформе .NET для получения верифицируемого MSIL-кода.

Вы можете использовать преобразования const_cast и reinterpret_cast как самое крайнее средство, так как эти операции так же небезопасны, как и преобразования в стиле С. Тем не менее, они необходимы для того, чтобы полностью заменить преобразование типов в старом стиле.

Операция static_cast осуществляет преобразование родственных типов, например, указателя на один класс в указатель на другой тип из той же иерархии классов, перечислений в целые типы или типа с плавающей точкой в интегральный.

Операция reinterpret_cast управляет преобразованиями между несвязанными типами, например, целых в указатели или указателей в другие (несвязанные) указатели.

Такое различие между операциями static_cast и reinterpret_cast позволяет компилятору осуществлять минимальную проверку типов при static_cast, а программисту – легче обнаружить опасные преобразования, представляемые reinterpret_cast. Некоторые преобразования static_cast являются переносимыми, но reinterpret_cast практически никогда непереносимы. Хотя никаких гарантий относительно reinterpret_cast дать нельзя, в результате обычно получается значение нового типа, состоящее из той же цепочки бит, что и аргумент. То, что результатом пребразования reinterpret_cast можно пользоваться, гарантировано только если тип его результата есть в точности тип, использованный для определения задействованного в преобразовании значения. Обратите внимание, что reinterpret_cast является той разновидностью преобразования, которой следует пользоваться при работе с указателями на функции.

Если у Вас возникло искушение пользоваться явным преобразованием, задумайтесь над тем, так ли это необходимо. В большинстве случаев в С++ нет нужды в явном преобразовании типов даже тогда, когда это необходимо в С или в более ранних версиях С++. Во многих программах можно (и следует) избежать явного преобразования типов. В остальных – локализовать их в нескольких процедурах.

С++ унаследовал от С форму записи (T)e, означающую любое преобразование, которое может быть выражено комбинацией операций static_cast, reinterpret_cast и const_cast для получения значения типа Т из выражения е. Такой стиль намного опаснее, чем именованные операции преобразования, потому что приведенную форму записи сложнее отслеживать в большой программе и вид преобразования, который имел ввиду програмист, не очевиден. Ведь (Т)е может осуществлять и переносимое преобразование между близкими типами, и непереносимое преобразование между несвязанными типами, и, наконец, аннулировать действие модификатора const для указателя. Не зная конкретно типы Т и е, невозможно сказать, что делает (Т)е.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]