Оператор преобразования типа

304
19 декабря 2016, 19:47

Какие аргументы и код возврата имеет оператор преобразования типа? В каких случаях неизбежно его использование?

Answer 1

Какие аргументы и код возврата имеет оператор преобразования типа?

  1. аргумент один - приводимое значение.
  2. оператор возвращает приведенное значение, причем, насколько я понимаю, это будет rvalue.

В каких случаях неизбежно его использование?

  1. в случае, когда компилятор не может "втихую" произвести преобразования типов. Для встроенных типов есть правила, которые определяют как типы могут преобразовываться. Например, char без проблем может быть преобразован в int и поэтому в ф-цию void f(int x) можно передать значение так: f('a');. При этом если существует версия ф-ции void f(char x), то компилятор должен будет выбрать именно ее.
  2. в случае, когда компилятор не может выбрать какую из перегруженных версий ф-ций нужно выбрать. Тогда программист выбирает конкретный вариант. Беря пример из первого случая, когда мы хотим значение 'a' оттрактовать именно как целое, то нам придется использовать оператор преобразования типа: f(static_cast<int>('a')).

Хочу обратить внимание, что хотя C++ и позволяет пользоваться приведением типа как в С (напр., double x = 10; int a = (int)x;), но лучше им не пользоваться, а пользоваться соответствующими операторами преобразования типа С++. Среди них есть и весьма интересные операторы (const_cast, dynamic_cast), работающие исключительно с указателями на классы и позволяющие, например, снять константность с указателя (может быть опасно, но нужно) и приводящие друг к другу базовые и производные классы. Второе может быть нужно для реализации полиморфизма на практике - работает с указателем на базовый класс, хотя на самом деле за ним скрывается объект производного класса.

Хорошую статью, а не мои путаные объяснения :-), про приведения типов можно посмотреть на ресурсе Алёна CPP

Answer 2

Я хотел бы заострить внимание на разнице между приведением (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!
READ ALSO
Сортировка массива

Сортировка массива

По результатам опроса прошлого года известен список 10 политических деятелей в порядке убывания их популярностиПроведен новый опрос

219
Оператор delete: удаление массива

Оператор delete: удаление массива

Здравствуйте:) Вот такой вопрос возник, почему вот этот после выполнения

196
OpenGl: Некорректное отображение квадратов

OpenGl: Некорректное отображение квадратов

ЗдравствуйтеЕсть программа, которая ищет ромбы в множестве заданных точек и выводит на экран координаты и площадь самого большого из них

183