Skip to the content.

Приведение типов


C-style cast

Синтаксис:

(type)a;

Пример:

int y = (int)x;

Из явных минусов:

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);

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