Преобразование типов C++ — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Новая страница: «__NOTOC__ {{цитата|автор=[http://ru.wikipedia.org/wiki/Бьярне_Страуструп Бьярне Страуструп]|Фундаментальны…»)
 
Строка 23: Строка 23:
 
В целом, для ''неявного'' преобразования указателей отведено существенно меньше свободы, чем для обычных базовых типов.  
 
В целом, для ''неявного'' преобразования указателей отведено существенно меньше свободы, чем для обычных базовых типов.  
  
Имеется специальный тип указателей: <tt>void *</tt> (подробнее см. <ref name="tcpppl" />, п. 5.6) — любой указатель может быть неявно преобразован к нему. Однако это правило не действует для указателей на функцию или на член класса. (<small>Последний факт иногда используется при реализации сложных приёмов программирования на C++, таких как «умные указатели», чтобы обезопасить программиста от выполнения [http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/shared_ptr.htm#conversions неявных преобразований].</small>).  
+
Имеется специальный тип указателей: <tt>void *</tt> (подробнее см. <ref name="tcpppl" />, п. 5.6) — любой указатель может быть неявно преобразован к нему. Однако это правило не действует для указателей на функцию или на член класса. (<small>Последний факт иногда используется при реализации сложных приёмов программирования на C++, таких как «[[http://ru.wikipedia.org/wiki/Умный_указатель умные указатели]]», чтобы обезопасить программиста от выполнения [http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/shared_ptr.htm#conversions неявных преобразований].</small>).  
  
 
Пару указателей <tt>void *</tt> можно сравнивать на равенство и неравенство, присваивать один указатель другому. Наконец, <tt>void *</tt> можно преобразовывать к другому типу указателя, при этом следует использовать ''явное преобразование типа'' (cast) одним из следующих способов:
 
Пару указателей <tt>void *</tt> можно сравнивать на равенство и неравенство, присваивать один указатель другому. Наконец, <tt>void *</tt> можно преобразовывать к другому типу указателя, при этом следует использовать ''явное преобразование типа'' (cast) одним из следующих способов:

Версия 22:36, 30 сентября 2010


« Фундаментальные типы могут преобразовываться один в другой невероятно большим количеством способов. По-моему, дозволяется слишком много преобразований.
»

Интегральные типы (int, char, bool, etc.) и типы с плавающей точкой в присваиваниях и арифметических выражениях можно свободно смешивать. Когда возможно, значения преобразуются так, чтобы не потерять информации. Неявные преобразования, сохраняющие значения, (например, bool к int) обычно называют продвижениями (promotion). К сожалению, преобразования, приводящие к потере значения, (например, присваивание вещественного числа целочисленной переменной, которое производится отбрасыванием дробной части) также могут осуществляться неявно.

Полный список правил преобразований можно прочитать в книге Б. Страуструпа[1], Приложение B, раздел 6.


Арифметические преобразования

В арифметических выражениях преобразования выполняются для того, чтобы привести значения к общему типу, который потом используется как тип результата. Если не учитывать беззнаковые типы, то можно удовлетвориться следующим набором неформальных правил:

  1. Если какой-либо из операндов принадлежит типу double, то и другой приводится к double.
  2. В противном случае, если какой-либо из операндов принадлежит типу float, то и другой приводится к float.
  3. В противном случае операнды типов short, char, bool приводятся к int (в случае bool значение false переводится в 0, а true — в 1).
  4. Наконец, если один из операндов типа long, то и другой приводится к long.

Условный оператор и условная операция (?:)

Следует помнить, что в качестве условия для условного оператора или условной операции может использоваться любое арифметическое выражение. В этом случае ненулевое значение трактуется как true, а 0 — как false.


Указатели

В целом, для неявного преобразования указателей отведено существенно меньше свободы, чем для обычных базовых типов.

Имеется специальный тип указателей: void * (подробнее см. [1], п. 5.6) — любой указатель может быть неявно преобразован к нему. Однако это правило не действует для указателей на функцию или на член класса. (Последний факт иногда используется при реализации сложных приёмов программирования на C++, таких как «[умные указатели]», чтобы обезопасить программиста от выполнения неявных преобразований.).

Пару указателей void * можно сравнивать на равенство и неравенство, присваивать один указатель другому. Наконец, void * можно преобразовывать к другому типу указателя, при этом следует использовать явное преобразование типа (cast) одним из следующих способов:

char * pc;
void * pv;
// ...
pc = (char *)pv; // (1) старый стиль C
pc = static_cast<char *>(pv); // (2) новый стиль C++

Конструкция (2) выглядит более громоздкой, но так сделано неспроста:

« Подобная форма явного преобразования типа [от void * к char * в примере] небезопасна и некрасива. Соответственно, использованный в примере тип преобразования static_cast был спроектирован при разработке языка таким образом, чтобы явно напоминать об этом.
Бьярне Страуструп
»

В общем случае рекомендуется использовать форму (2).

Ссылки

  1. 1,0 1,1 Страуструп Б. Язык программирования C++, 3-е изд.