Язык программирования C++. Вводный курс


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


Явное преобразование типов производится при помощи следующих операторов: static_cast, dynamic_cast, const_cast и reinterpret_cast. Заметим, что, хотя иногда явное преобразование необходимо, оно служит потенциальным источником ошибок, поскольку подавляет проверку типов, выполняемую компилятором. Давайте сначала посмотрим, зачем нужно такое преобразование.

Указатель на объект любого неконстантного типа может быть присвоен указателю типа

void*, который используется в тех случаях, когда действительный тип объекта либо неизвестен, либо может меняться в ходе выполнения программы. Поэтому указатель void*

иногда называют универсальным

указателем. Например:

int iva1;

int *pi = 0;

char *pc = 0;

void *pv;

 

pv = pi; // правильно: неявное преобразование

pv = pc; // правильно: неявное преобразование

 

const int *pci = &iva1;

pv = pci; // ошибка: pv имеет тип, отличный от const void*;

const void *pcv = pci; // правильно

Однако указатель void* не может быть разыменован непосредственно. Компилятор не знает типа объекта, адресуемого этим указателем. Но это известно программисту, который хочет преобразовать указатель void* в указатель определенного типа. С++ не обеспечивает подобного автоматического преобразования:

#inc1ude <cstring>

int ival = 1024;

void *pv;

int *pi = &iva1;

const char *pc = "a casting call";

 

void mumble() {

    pv = pi; // правильно: pv получает адрес ival

    pc = pv; // ошибка: нет стандартного преобразования

 

    char *pstr = new char[ str1en( pc )+1 ];

    strcpy( pstr, pc );

}

Компилятор выдает сообщение об ошибке, так как в данном случае указатель pv

содержит адрес целого числа ival, и именно этот адрес пытаются присвоить указателю на строку. Если бы такая программа была допущена до выполнения, то вызов функции strcpy(), которая ожидает на входе строку символов с нулем в конце, скорее всего привел бы к краху, потому что вместо этого strcpy() получает указатель на целое число. Подобные ошибки довольно просто не заметить, именно поэтому С++ запрещает неявное преобразование указателя на void в указатель на другой тип. Однако такой тип можно изменить явно:




Начало  Назад  Вперед



Книжный магазин