Читать интересную книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 309 310 311 312 313 314 315 316 317 ... 337
class="p1">Оператор delete вызывает деструкторы каждого операнда, если они есть. Обратите внимание на то, что деструктор может быть виртуальным (раздел A.12.3.1).

A.5.7. Операторы приведения

Существуют четыре оператора приведения к типу.

Динамическое приведение обычно используется для навигации по иерархии классов, если указатель 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++ приведено ниже (opt означает “необязательный”).

инструкция:

  объявление

  { список_инструкции opt }

 try { список_инструкции opt } список_обработчиков

  выражение opt;

  инструкция_выбора

  инструкция_итерации

  инструкция_с_метками

  управляющая_инструкция

инструкция_выбора:

  if (условие) инструкция

  if (условие) инструкция else инструкция

  switch (условие) инструкция

инструкция_итерации:

  while (условие) инструкция

  do инструкция while (выражение);

  for (инструкция_инициализации_for условие opt; выражение opt) инструкция

инструкция_с_метками:

  case константное_выражение: инструкция

  default: инструкция

  identifier: инструкция

управляющая_инструкция:

  break; 

  continue;

  return выражение opt;

  goto идентификатор;

список_инструкции:

  инструкция список_инструкции opt

условие:

  выражение

  спецификатор_типа объявляемый_объект = выражение

инструкция_инициализации_for:

  выражение opt;

  спецификатор_типа объявляемый_объект = выражение;

список_обработчиков:

  catch (объявление_исключения) { список_инструкции opt }

  список_обработчиков список_обработчиков opt

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

• Итерация (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> v;

  int x;

  while (cin>>x) {

    if (x==terminator) break; // выход из цикла while

    v.push_back(x);

  }

  for (int i = 0; i<v.size() && i<n; ++i) {

    if (v[i]==*p)

      return p;

    else

      ++p;

  }

  return 0;

}

A.7. Объявления

Объявление (declaration) состоит из трех частей:

• имя объявляемой сущности;

• тип объявляемой сущности;

• начальное значение объявляемой сущности (во многих случаях необязательное).

Мы можем объявлять следующие сущности:

• объекты встроенных типов и типов, определенных пользователем (раздел A.8);

• типы, определенные пользователем (классы и перечисления) (разделы A.10–А.11, глава 9);

• шаблоны (шаблонные классы и функции) (раздел A.13);

• альтернативные имена (раздел A.16);

• пространства имен (разделы A.15 и 8.7);

• функции (включая функции-члены и операторы) (раздел A.9, глава 8);

• перечисления (значения перечислений) (разделы A.11 и 9.5);

• макросы (разделы A.17.2 и 27.8).

A.7.1. Определения

Определение с инициализацией, резервирующее область памяти или как-то иначе поставляющую компилятору всю информацию, необходимую для использования имени в программе, называется определением (definition). Каждый тип, объект и функция в программе должны иметь только одно определение. Рассмотрим примеры.

double f();               // объявление

double f() { /* ... */ }; // также определение

extern const int x;       // объявление

int y;                    // также определение

int z = 10;               // определение с явной инициализацией

Константы должны быть инициализированы. Для этого используется инициализатор, если константа не объявлена с помощью ключевого слова extern (в таком случае инициализатор вместе с определением должны быть расположены в другом месте) или если константа не имеет тип, имеющий конструктор по умолчанию (раздел A.12.3). Константные члены класса должны инициализироваться в каждом конструкторе с помощью инициализатора (раздел A.12.3). 

A.8. Встроенные типы

 Язык C++ имеет много фундаментальных типов и типов, составленных из фундаментальных типов с помощью модификаторов.

Здесь T означает “некий тип”, поэтому существуют варианты long unsigned int, long double, unsigned char и const char* (указатель на константный символ char). Однако эта система не совсем полная; например, в ней нет типа short double (его роль играет тип float); типа signed bool (совершенно бессмысленного); типа short long int (это было бы лишним) и типа long long long long int. Некоторые компиляторы в ожидании стандарта C++0x допускают тип long long int (читается как “очень длинный целый тип ”). Гарантируется, что тип

1 ... 309 310 311 312 313 314 315 316 317 ... 337
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп.
Книги, аналогичгные Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Оставить комментарий