Операции преобразования. typeid
Операцию преобразования
(тип)выражение можно записывать в форме
тип(выражение), если имя типа состоит из одной лексемы. Правила преобразований в С++ совпадают с С, за исключением того, что преобразование
void * к указателю любого типа требует явный вызов операции преобразования (см. пример ниже).
Любое преобразование является источником потенциальных ошибок, поэтому в С++ были введены
четыре специализированных операции преобразования. При использовании этих операций компилятор сможет выполнить проверку на допустимость преобразования на этапе компиляции или при выполнении. Вызовы этих операций легче находить в тексте программы, чем вызовы в форме, унаследованной от С, что упрощает модификацию программы.
const_cast<тип>(выражение)
Служит для добавления или удаления модификатора
const или
volatile (антоним
register). Так как добавление
const не требует явного вызова операции преобразования, то вызывать эту операцию необходимо только для удаления
const.
dynamic_cast<тип>(выражение)
Служит для преобразования указателя или ссылки на объект одного класса в указатель или ссылку соответственно на объект другого класса в пределах одной иерархии классов. Оба класса должны иметь хотя бы один виртуальный метод, например, деструктор. Если преобразование недопустимо, то в случае преобразования указателей операция возвращает нулевой указатель, а в случае ссылок – исключение
bad_cast. Для повышающего преобразования (к указателю или ссылке на объект базового класса) явного вызова операции преобразования не требуется, поэтому эта операция используется для понижающего (к указателю или ссылке на объект производного класса) или перекрёстного преобразования.
static_cast<тип>(выражение)
Служит для вызова преобразований для стандартных типов данных (например, вещественное в целое и обратно) и преобразований, определенных программистом. Также можно использовать для повышающих и понижающих преобразований в пределах одной иерархии классов
без проверки, при этом не требуется наличие виртуальных методов. Так как в большинстве случаев такие преобразования выполняются даже без явного вызова, то можно использовать форму (тип)выражение или тип(выражение) в тех случаях, когда необходимо получить значение определенного типа, а форму
static_cast<тип>(выражение) применять только для потенциально опасных понижающих преобразований.
reinterpret_cast<тип>(выражение)
Служит для преобразований не связанных между собой типов, например, указатель в целое и обратно, указатель
void * к любому указателю. При переносе программы на компьютер с процессором другой архитектуры или разрядностью все операции преобразования этого вида должны тщательно проверяться.
int *p1=(int *)calloc(100,sizeof(int)); //
int *p2=reinterpret_cast<int *>(calloc(100,sizeof(int))); //
Операции
typeid в качестве аргумента можно указать любое выражение или тип (как операции
sizeof). Операция возвращает информацию о типе выражения в виде объекта класса
type_info. Если определить тип выражения невозможно, операция порождает исключение
bad_typeid. Метод
name() класса
type_info возвращает строку
char * с именем типа, а операции
== и
!= позволяют сравнить два типа.