Приведение типов
C-style cast
Синтаксис:
(type)a;
Пример:
int y = (int)x;
Из явных минусов:
- конструкцию по типу static_cast намного проще обнаружить при поиске по проекту чем c-style
- c-style абсолютно без разницы какой тип преобразовывать в какой, ему неважна безопасность преобразования. Для него вполне допустимо преобразование int в указатель на int
- C-style выполняется в runtime и не проверяется на этапе компиляции
- c-style по сути самое медленное преобразование, так как оно перебирает:
- const_cast
- static_cast
- static_cast + const_cast
- reinterpet_cast
- reinterpet_cast + const_cast
static_cast
Синтаксис:
static_cast<type>(a);
Пример:
int y = static_cast<int>(x);
Преобразует один статический тип в другой статический тип. static_cast ограничивает недопустимое приведение типов (например int в int * недопустимо), соответственно он безопаснее чем c-style. Проверка происходит на этапе компиляции.
При приведении типов, например size_t к _uint32_t__, компилятор скорее всего выдаст подобное предупреждение: _conversion from ‘size_t’ to ‘uint32_t’, possible loss of data. И правильно сделает: типы разного размера и действительно в определенных случаях можно потерять данные, но ошибку можно убрать используя __static_cast
dynamic_cast
Синтаксис:
dynamic_cast<type *>(a);
dynamic_cast<type &>(a);
Пример:
Parent * p;
Child * c = dynamic_cast<Child *>(p);
Допустим у нас есть родительский класс Parent и дочерний класс Child. Так же мы имеем указатель на Parent, который на самом деле указывает на дочерний экземпляр (такое можно). Что бы в такой ситуации достучаться до полей дочернего класса нам нужно даунгрейнуть указатель с указателя на родителя до указателя на дочерний класс.
В случае неправильного приведения будет исключение std::bad_cast, а для указателей возвращен 0.
const_cast
Синтаксис:
const_cast<type>(a);
Пример:
int x = 10;
const int * y = &x;
int * z = const_cast<int *>(y);
Снимает (либо добавляет!) cv qualifiers: const и volatile (константность и отмена оптимзации компилятором переменной). Проверка происходит на этапе компиляции.
reinterpret_cast
Синтаксис:
reinterpret_cast<type>(a);
Пример:
reinterpret_cast<int *>(7);
Приведение типов без проверки, непосредственное указание компилятору. Наименее безопасное приведение, способно привести два несовместимых типа.