Динамическое приведение обычно используется для навигации по иерархии классов, если указатель p
— указатель на базовый класс, а класс D
— производный от базового класса. Если операнд v
не относится к типу D*
, то эта операция возвращает число 0
. Если необходимо, чтобы операция dynamic_cast
в случае неудачи не возвращала 0
, а генерировала исключение bad_cast
, то ее следует применять к ссылкам, а не к указателям. Динамическое приведение — единственное приведение, опирающееся на проверку типов во время выполнения программы.
Статическое приведение используется для “разумных преобразований,” т.е. если операнд v может быть результатом неявного преобразования типа T
(см. раздел 17.8).
Оператор reinterpret_cast
используется для реинтерпретации комбинации битов. Его переносимость не гарантируется. Фактически лучше считать, что он является вообще не переносимым. Типичным примером реинтерпретации является преобразование целого числа в указатель, чтобы получить машинный адрес в программе (см. разделы 17.8 и 25.4.1).
Приведения в стиле языка С и функциональные приведения могут выполнить любое преобразование типа, которое можно осуществить с помощью оператора static_cast
или reinterpret_cast
в сочетании с оператором const_cast
.
Приведений лучше избегать. Во многих ситуациях их использование свидетельствует о плохом стиле программирования. Исключения из этого правила представлены в разделах 17.8 и 25.4.1. Приведение в стиле языка С и функциональные приведения имеют ужасное свойство: они позволяют вам не вникать в то, что именно они делают (см. раздел 27.3.4). Если вы не можете избежать явного преобразования типа, лучше используйте именованные приведения.
A.6. Инструкции
Грамматическое определение инструкций языка C++ приведено ниже (
try
if
if
else
switch
while
do
while
for
case
default:
identifier:
break;
continue;
return
goto
catch
Обратите внимание на то, что объявление — это инструкция, а присваивание и вызов функции являются выражениями. К этому определению следует добавить следующий список.
• Итерация (for
и while
); см. раздел 4.4.2.
• Ветвление (if
, switch
, case
и break
); см. раздел 4.4.1. Инструкция break
прекращает выполнение ближайшей вложенной инструкции switch
, while
, do
или for
. Иначе говоря, следующей будет выполнена инструкция, следующая за последней в теле одной из перечисленных выше инструкций.
• Выражения; см. разделы A.5 и 4.3.
• Объявления; см. разделы A.6 и 8.2.
• Исключения (try
и catch
); см. разделы 5.6 и 19.4.
Рассмотрим пример, созданный просто для того, чтобы продемонстрировать разнообразие инструкций (какую задачу они решают?).
int* f(int p[],int n)
{
if (p==0) throw Bad_p(n);
vector
int x;
while (cin>>x) {
if (x==terminator) break; // выход из цикла while
v.push_back(x);
}
for (int i = 0; i
if (v[i]==*p)
return p;
else
++p;
}
return 0;
}
A.7. Объявления
• имя объявляемой сущности;
• тип объявляемой сущности;