Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
###Cpp_лкц1_1.09_11_#дляБАК#29_01_12.doc
Скачиваний:
40
Добавлен:
29.04.2019
Размер:
6.42 Mб
Скачать

Часть II. Объектно-ориентированное программирование

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

ПРИМЕЧАНИЕ

В ранних версиях компиляторов C++ операции приведения типа const_cast, dynamic_cast, reinterpret_cast и static_cast не поддерживаются.

Операция const_cast

Операция служит для удаления модификатора const. Как правило, она используется при передаче в функцию константного указателя на место формального параметра, не имеющего модификатора const. Формат операции:

const_cast <тип> (выражение)

Обозначенный тип должен быть таким же, как и тип выражения, за исключением модификатора const. Обычно это указатель. Операция формирует результат указанного типа.

Необходимость введения этой операции обусловлена тем, что программист, реализующий функцию, не обязан описывать не изменяемые в ней формальные параметры как const, хотя это и рекомендуется. Правила C++ запрещают передачу константного указателя на место обычного. Операция constcast введена для того, чтобы обойти это ограничение. Естественно, функция не должна пытаться изменить значение, на которое ссылается передаваемый указатель, иначе результат выполнения программы не определен.

Пример:

void print(int *p){ // Функция не изменяет значение *р cout « *р;

}

const int *p;

/* print(p): Ошибка, поскольку р объявлен как указатель на константу */

Операция const_cast используется в том случае, когда программист уверен, что в теле функции значение, на которое ссылается указатель, не изменяется. Естественно, если есть возможность добавить к описанию формального параметра модификатор const, это предпочтительнее использования преобразования типа при вызове функции.

Операция dynamic_cast

Операция применяется для преобразования указателей родственных классов иерархии, в основном — указателя базового класса в указатель на производный

Глава 8. Преобразования типов

233

класс, при этом во время выполнения программы производится проверка допустимости преобразования.

Формат операции:

dynamic_cast <тип *> (выражение)

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

Преобразование из базового класса в производный называют понижающим (downcast), так как графически в иерархии наследования принято изображать производные классы ниже базовых. Приведение из производного класса в базовый называют повышающим (upcast), а приведение между производными классами одного базового или, наоборот, между базовыми классами одного производного — перекрестным (crosscast).

Повышающее преобразование

Выполнение с помощью операции dynamic_cast повышающего преобразования равносильно простому присваиванию:

class В{ /* ... */ };

class С: public В{ /* ... */ };

С* с = new С;

В* b = dynamic_cast<B*>(c); // Эквивалентно В* b = с;

Понижающее преобразование

Чаще всего операция dynamic_cast применяется при понижающем преобразовании — когда компилятор не имеет возможности проверить правильность приведения.

Производные классы могут содержать функции, которых нет в базовых классах. Для их вызова через указатель базового класса нужно иметь уверенность, что этот указатель в действительности ссылается на объект производного класса. Такая проверка производится в момент выполнения приведения типа с использованием RTTI (run-time type information) — «информации о типе во время выполнения программы». Для того чтобы проверка допустимости могла быть выполнена, аргумент операции dynamic_cast должен быть полиморфного типа, то есть иметь хотя бы один виртуальный метод (см. с. 205).

1 Если выражение равно нулю, результат также равен нулю.

234