Явно преобразуване
Може да се каже, че е малко
разточително да се изпълняват две операции за конвертиране в един смесен
оператор i = i + 3.14159. Понеже типът на резултата е int изглежда по-разумно да
се свива операнда от тип double вместо да се разширява i до тип double и след
това сумата да се свива до int.
Една от причините за явното конвертиране
е отхвърлянето на стандартното преобразуване. Например,
i = i +
int(3.14159);
Сега 3.14159 се конвертира към тип int със стойност 3. Тази
стойност се добавя към, и после се присвоява на i.
Едно предварително
дефинирано стандартно конвертиране позволява да бъде прсвояван указател от
произволен даннов тип на указател от тип void*. Указателят void* се използува
винаги когато конкретният тип на даден обект е неизвестен или ще се променя при
известни обстоятелства. Указателят void* понякота се нарича обобщен указател
поради способността му да адресира обекти от произволен даннов
тип.
Обаче, към данните, сочени от указател void* не можем да се обръщаме
директно. ( Няма налична информация за тип, от която да се ръководи компилатора
при интерпретирането на сочената битова последователност). По-скоро указателят
void* трябва първо да бъде конвертиран към конкретен тип.
В С++, обаче,
няма предварително дефинирано преобразуване на указател void* към указател от
конкретен тип понеже това е потенциално опасно. Например, ако се опитате да
присвоите указател от тип void* на указател към какъвто и да е обект ще получите
грешка по време на компилация:
int i;
void *vp;
int *ip =
&i;
double *dp;
vp = ip; // ok:
explicit castdp =vp; //
error:
no standart convertion:
unsafe
Втората причина за явното
конвертиране е да бъде заобиколено проверяването на типовете. Изобщо, С++
разрешава всяка стойност да бъде явно конвертрана към произволен даннов тип. При
явното конвертиране, обаче, програмистът носи отговорност за безопасността на
преобразуването на типовете. Например,
dp = (int*)vp; // ok:
explicit
cast*dp = 3=14; // trouble if dp addresses i
Третата причина за явното
конвертиране е да бъде избегната ситуацията, когато е възможно повече от едно
конвертиране. Ние ще разгледаме този случай по-задълбочено в раздел 4.3 при
обсъждането на презаредимите именана функции.
Даден е следния набор от
идентификатори:
char ch;
unsigned char unChar;
short
sh;
unsigned short unShort;
int intVal;
unsigned int unInt;
long
longVal;
float f1;
Упражнение 3-11. Определете кои от следните
присвоявания не са безопасни поради възможното стесняване:
(a) sh =
intVal (e) longVal = unInt (b)intVal = longVal
(f) unInt = f1
(c) sh =
unChar
(g) intVal = unShort
Упражнение 3-12. Определете типа на
следните изрази:
(a) ‘a’ - 3
(b) intVal * longVal - ch
(c) f1 +
longVal / sh
(d) unInt + (unsigned int) longVal
(e) ch + unChar + longVal
+ unInt