Какие аргументы и код возврата имеет оператор преобразования типа? В каких случаях неизбежно его использование?
Какие аргументы и код возврата имеет оператор преобразования типа?
В каких случаях неизбежно его использование?
char без проблем может быть преобразован в int и поэтому в ф-цию void f(int x) можно передать значение так: f('a');. При этом если существует версия ф-ции void f(char x), то компилятор должен будет выбрать именно ее.'a' оттрактовать именно как целое, то нам придется использовать оператор преобразования типа: f(static_cast<int>('a')).Хочу обратить внимание, что хотя C++ и позволяет пользоваться приведением типа как в С (напр., double x = 10; int a = (int)x;), но лучше им не пользоваться, а пользоваться соответствующими операторами преобразования типа С++. Среди них есть и весьма интересные операторы (const_cast, dynamic_cast), работающие исключительно с указателями на классы и позволяющие, например, снять константность с указателя (может быть опасно, но нужно) и приводящие друг к другу базовые и производные классы. Второе может быть нужно для реализации полиморфизма на практике - работает с указателем на базовый класс, хотя на самом деле за ним скрывается объект производного класса.
Хорошую статью, а не мои путаные объяснения :-), про приведения типов можно посмотреть на ресурсе Алёна CPP
Я хотел бы заострить внимание на разнице между приведением (cast) и преобразованием (conversion).
При преобразовании меняется машинное (битовое) представление переменой, а при приведении (cast) нет, меняются правила манипулирования этой переменной.
Пример преобразований
int a = 100;
printf ("int a = %d sizeof(a): %ld (double)a = %e sizeof(double): %ld\n",
a, (long)sizeof(a), (double)a, (long)sizeof((double)a));
printf ("sizeof(sizeof(a)) = %d\n", (int)sizeof(sizeof(a)));
результат
int a = 100 sizeof(a): 4 (double)a = 1.000000e+02 sizeof(double): 8
sizeof(sizeof(a)) = 8
Это пример с 64-бит машины. Преобразование в размере и битовом представлении между int и double очевидны.
Подробнее о sizeof. Тип оператора sizeof это 'long unsigned int', поэтому для переносимости между 32-бит (там 'long unsigned int' занимает 4 байта) и 64-бит
в плане проверки компилятором формата в printf требуется явное преобразование типа.
В принципе, преобразование (int)sizeof(...) идет с усечением значения (старших разрядов), в данном случае это несущественно (т.к. числа маленькие). Но, правильным будет
использовать "%ld" в формате и (long)sizeof для переносимости при компиляции.
На практике приведение типа чаще всего необходимо при работе с указателями.
Например, если есть переменная типа int, а мы хотим посмотреть на "текст в ней", то без cast-а не обойтись. Или наоборот:
const char *p = "cast";
int *ip = (int *)p;
printf ("%s = %d\n", (char *)ip, *ip);
int b = 1414742339;
printf ("А это десятичное число %d = ", b);
for (p = (const char *)&b; (int *)p < &b + 1; p++)
putchar(*p);
long long bye = 0xa216579420a;
// long long для переносимости с 32-bit
// нам тут нужно 5 байт для string terminated 0
puts((char *)&bye);
результат
cast = 1953718627
А это десятичное число 1414742339 = CAST
Bye!
Продвижение своими сайтами как стратегия роста и независимости