Иногда бывает необходимо явно преобразовать значение одного типа в значение другого. Результатом явного преобразования будет значение указанного типа, полученное из значения другого типа. Например:
float r = float(1);
Здесь перед присваиванием целое значение 1 преобразуется в значение с плавающей точкой 1.0f. Результат преобразования типа не является адресом, поэтому ему присваивать нельзя (если только тип не является ссылкой).
Существуют два вида записи явного преобразования типа: традиционная запись, как операция приведения в С, например, (double)a и функциональная запись, например, double(a). Функциональную запись нельзя использовать для типов, которые не имеют простого имени. Например, чтобы преобразовать значение в тип указателя, надо или использовать приведение
char* p = (char*)0777;
или определить новое имя типа:
typedef char* Pchar; char* p = Pchar(0777);
По мнению автора, функциональная запись в нетривиальных случаях предпочтительнее. Рассмотрим два эквивалентных примера:
Pname n2 = Pbase(n1->tp)->b_name; // функциональная запись Pname n3 = ((Pbase)n2->tp)->b_name; // запись с приведением
Поскольку операция -> имеет больший приоритет, чем операция приведения, последнее выражение выполняется так:
((Pbase)(n2->tp))->b_name
Используя явное преобразование в тип указателя можно выдать данный объект за объект произвольного типа. Например, присваивание
any_type* p = (any_type*)&some_object;
позволит обращаться к некоторому объекту (some_object) через указатель p как к объекту произвольного типа (any_type). Тем не менее, если some_object в действительности имеет тип не any_type, могут получиться странные и нежелательные результаты.
Если преобразование типа не является необходимым, его вообще следует избегать. Программы, в которых есть такие преобразования, обычно труднее понимать, чем программы, их не имеющие. В то же время программы с явно заданными преобразованиями типа понятнее, чем программы, которые обходятся без таких преобразований, потому что не вводят типов для представления понятий более высокого уровня. Так, например, поступают программы, управляющие регистром устройства с помощью сдвига и маскирования целых, вместо того, чтобы определить подходящую структуру (struct) и работать непосредственно с ней. Корректность явного преобразования типа часто существенно зависит от того, насколько программист понимает, как язык работает с объектами различных типов, и какова специфика данной реализации языка. Приведем пример: