Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tema_7.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
91.14 Кб
Скачать

12

Тема 7

Преобразование типов. Указатели на функции. Cтруктура программы

1 Использование описания typedef

Описания typedef позволяет вводить синонимы для определенных ранее типов. Имена, определенные с помощью typedef, можно использовать так же, как спецификаторы встроенных типов и производных типов, а также типов, определенных пользователем. В описании после ключевого слова typedef следует спецификатор типа и идентификатор. Этот идентификатор и есть синоним для указанного типа.

typedef int *PArray[10]; // Тип массива из 10 указателей на целое

PArray p; // Переменная описанного типа

Синонимы типов, определенные с помощью typedef, могут участвовать в другом определении typedef. Описание typedef не определяет нового (пользовательского) типа, а только определяет синоним для существующего.

Наряду с базовыми типами данных, имена типов, полученные с помощью описания typedef, можно использовать в таких операциях, как приведение типа, sizeof, new, а также в объявлениях.

2 Преобразование типов

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

  • В арифметическом выражение с операндами разных типов все операнды приводятся к наибольшему типу из встретившихся. Это называется арифметическим преобразованием.

  • При присваивании значения выражения одного типа объекту другого типа результирующим является тип объекта, которому значение присваивается.

  • При передач функции аргумента, тип которого отличается от типа соответствующего формального параметра, тип фактического аргумента приводится к типу параметра.

Если тип объекта требует для своего представления меньше битов (является более узким типом), чем тип присваиваемого объекту значения, то говорят, что происходит сужение типа. Сужение типа может привести к потере данных. Преобразование беззнакового типа к знаковому тоже считается сужением типа. В арифметическом выражении более широкий тип данных становится результирующим типом - это расширение типа.

В приведенном фрагменте программы

int i = 3.14;

i = i + 3.14;

произойдут три преобразования типа. Константа 3.14 преобразуется к типу int (i равно 3). Во второй строке значение i расширяется до double. Результат 6.14 затем сужается до int. Это суженное значение присваивается i. Переменная i теперь содержит значение 6.

Явное преобразование типов производится при помощи следующих операторов: static_cast, dynamic_cast, const_cast и reinterpret_cast. Хотя иногда явное преобразование необходимо, оно служит потенциальным источником ошибок, поскольку подавляет проверку типов, выполняемую компилятором.

С применением static_cast осуществляются те преобразования, которые могут быть сделаны неявно, на основе правил по умолчанию. С помощью static_cast указатель void* можно преобразовать в указатель определенного типа, арифметическое значение – в значение перечисления (enum), а базовый класс – в производный. Данное преобразование работает только для связанных типов и только во время компиляции, что позволяет не смешивать различные подходы к преобразованиям. В следующем примере преобразование выполняется для того, чтобы на экран выводилось число, а не символ с соответствующим кодом:

char byte_value = 32;

cout << static_cast<int>(byte_value);

Оператор dynamic_cast применяется при идентификации типа во время выполнения (run-time type identification) и будет рассмотрен при изучении классов.

Преобразование const_cast используется для добавления или удаления из типа переменной модификаторов const и volatile (последний модификатор используется для отображения того факта, что переменная может быть изменена фоновым процессом, подпрограммой-обработчиком прерываний и т.д.). В выражении

const_cast< T > (arg)

T и arg должны быть одного и того же типа, за исключением модификаторов const и volatile. Преобразование осуществляется во время выполнения. Результат имеет тип T. Чаще всего используется для преобразования типов указателей и ссылок:

int i = 2;

const int *p1 = &i;

int* p2 = const_cast<int*>(p1); // Без const_cast будет ошибка компиляции

*p2 = 3; // Можно модифицировать i через p2

Преобразование reinterpret_cast работает с внутренними представлениями объектов (re-interpret – другая интерпретация того же внутреннего представления), причем правильность этой операции целиком зависит от программиста. В выражении

reinterpret_cast< T > (arg)

тип T должен быть типом указателя, ссылки, арифметическим типом, указателем на функцию или член класса.

Устаревшая форма явного преобразования имеет два вида:

// появившийся в C++ вид

type (expr);

// вид, существовавший в C

(type) expr;

и может применяться вместо операторов static_cast, const_cast и reinterpret_cast.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]