Как известно, в С++ реализованы явные и неявные преобразования типов (см. п. 4 в [1]). Неявные преобразования выполняются при вычислениях выражений и присваивании. Коротко правила преобразования по умолчанию можно описать такой цепочкой (см. п. п. 5/9 в [1]):
[[char,short]->int]->unsigned int->long->unsigned long->float->double-> long double
Это не означает, что преобразование типа int в double обязательно выполняется строго последовательно, как прописано в цепочке. Просто менее «объемный» тип преобразуется к более «объемному». Типы charnshort перед выполнением операции всегда сначала преобразуются в int, а затем выполняется операция. При этом могут выполняться другие неявные преобразования, например intBdouble. Кроме того, к типу int по умолчанию приводится перечислимый тип enum.
По умолчанию может выполняться и обратное преобразование, например float в int. Однако подобного рода преобразования связаны с потерей информации (дробная часть просто отбрасывается), поэтому они называются сужающими приведениями. Хороший компилятор обязательно предупреждает о таких операциях.
Явные преобразования язык С++ поначалу унаследовал от С. Операция преобразования в стиле С может записываться в форме
(тип) выражение
Первоначально в С++ явное преобразование записывалось тоже в короткой форме, хотя и более привычной:
тип (выражение)
С точки зрения результата эти две формы абсолютно эквивалентны. Брюс Эккель предупреждает [11], что «вы намеренно открываете брешь в системе безопасности типов С++ и запрещаете компилятору сообщать о неправильных преобразованиях типов». Ему вторит Б. Страуструп в [2], отмечая, что «явное преобразование типа ... используется неоправданно часто и является основным источником ошибок». Поэтому в стандарт С++ включены новые операторы явного преобразования типов, которые не являются взаимозаменяемыми (см. п. 5.4 в [1]):
static_cast<тип>(выpaжeниe) // см. п. п. 5.2.9 в [1]
ге^егрге^са5^тип>(выражение) // см. п. п. 5.2.10 в [1]
dynamic_cast<™n> (выражение) // см. п. п. 5.2.7 в [1]
Кроме того, есть еще оператор отмены константности const_cast<> (см. п. п. 5.2.11 в [1]). Как видим, операторы достаточно «длинные», поэтому прежде, чем писать преобразование, любой программист подумает, а надо ли это делать. Рассмотрим оператор явного приведения типа
static_cast<T>(e)
В стандарте С++ сказано (см. п. п. 5.2.9/2 [1]), что такое приведение типа возможно только в том случае, если имеет смысл конструкция Т t (е). Здесь е — выражение, приводимое к типу Т, тип Т — это либо встроенный тип, либо реализованный класс, at — некоторая временная переменная. С практической точки зрения это означает, что данный оператор выполняет приведение типов с проверкой во время компиляции. Например, все преобразования в указанной ранее цепочке можно выполнять явно при помощи оператора static_cast<>.
Оператор reinterpret__cast<> выполняет преобразование типов без проверки при компиляции. На практике такое преобразование часто необходимо тогда, когда точно известно, что объекты разных типов занимают в памяти одинаковое количество байтов и фактического преобразования делать как раз не нужно. Например, с помощью этого оператора можно выполнять преобразования указателей (что довольно часто и делается). Б. Страуструп в [2] и стандарт (см. п. п. 5.2.10/3 в [1]) предупреждают, что выражение преобразования с оператором reinterpret_ cast<> зависит от реализации и «практически никогда не переносимо». Примеры применения этих операторов мы еще увидим.
Оператор const_cast<> позволяет временно отменить константность. Рассмотрим несколько искусственный пример функции с константной ссылкой в качестве параметра:
int ff(const int &а) // константный параметр { const_cast<int &>(а) = 6; // отмена "константности" return а; }
Система Visual C++.NET 2003 транслирует данное определение без ошибок, и следующий вызов выведет на экран число 6:
cout<<ff(8)<<endl;
Совершенно корректным будет и вызов cout<<ff(k)<<endl;
Здесь к — некоторая целочисленная переменная. Однако данный вызов имеет побочный эффект: переменная к изменяет значение и становится равной 6. Интересно, что изменения не происходит, если переменная к объявлена как константа:
const int k = 3;
Visual C++.NET 2003 никаких сообщений (и даже предупреждений) не выдает. Если вы решили положить новый паркет в офисе, тогда вам нужна компания Ламинат Шара. Еще один оператор преобразования — dynami c_cast<> — выполняет преобразование во время работы программы и применяется для преобразования указателей и ссылок родственных полиморфных классов1 — его мы изучим в дальнейшем.
Опубликовал Kest
September 12 2013 19:23:48 ·
0 Комментариев ·
6188 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.