Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4132

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Глава 10. Дополнения к типам данных языка С 

141 

Оператор 

const_cast

 

Оператор 

const_cast

  отменяет  для  переменных  действие  квали-

фикаторов 

const

 и 

volatile

. При этом тип переменной не должен 

изменяться.  Работает  оператор 

const_cast

  на  этапе  компиляции 

программы. 
Оператор 

const_cast

 используется главным образом для преобра-

зования типов указателей на константы, отменяя действие моди-
фикаторов доступа 

const

 или 

volatile

В  листинге  10.6  приведен  пример  использования  оператора 

const_cast

Листинг 10.6. Использование оператора 

const_cast

 

#include <iostream> 
using namespace std; 
 
int foo(int* p) { return *p; } 
int main() 

  const int n = 10; 
  cout << foo(const_cast<int*>(&n)) << endl; 
 
  return 0; 

Отметим,  что  при  попытке  записи  в  константный  объект  через 
указатель, тип которого изменен оператором 

const_cast

, поведе-

ние  программы  не  определено.  Чаще  всего  это  вызовет  ошибку, 
так константные объекты обычно размещаются в памяти, в кото-
рую запрещена запись. 

Оператор 

reinterpret_cast

 

Оператор 

reinterpret_cast

  используется  для  преобразования  ти-

па выражения, но сохранения его битового представления. Рабо-
тает оператор 

reinterpret_cust

 на этапе компиляции программы. 

В  листинге  10.7  приведен  пример  использования  оператора 

reinterpret_cust


background image

Часть II. Язык программирования С++ 

142 

Листинг 10.7. Использование оператора 

reinterpret_cast

 

#include <iostream> 
using namespace std; 
 
int main() 

  int  n = (int)'a' + (int)'b' * 256; 
  char*  p = reinterpret_cast<char*>(&n); 
 
  cout << p[0] << p[1] << endl;  // печатает ab 
 
  return 0; 

Оператор 

dynamic_cast

 

Оператор 

dynamic_cast

 используется для преобразования указате-

ля или ссылки на производный класс соответственно в указатель 
или ссылку на базовый класс при условии, что эти классы поли-
морфны.  Работает  оператор 

dynamic_cast

  на  этапе  исполнения 

программы,  причем  при  компиляции  программы  должна  быть 
включена опция поддержки проверки типов объектов. 
В  листинге  10.8  приведен  пример  использования  оператора 

dynamic_cast

Листинг 10.8. Использование оператора 

dynamic_cast

 

#include <iostream> 
using namespace std; 
 
struct Base 

  virtual void foo() { cout << "Base" << endl; } 
}; 
struct Derived: Base 

  virtual void foo() { cout << "Derived" << endl; } 
}; 


background image

Глава 10. Дополнения к типам данных языка С 

143 

void foo(Base* pb) 

  Derived* pd = dynamic_cast<Derived*>(pb); 
  pd->foo(); 

int main() 

  Derived d; 
  Derived* pd = &d; 
  foo(pd); 
 
  return 0; 

10.6. Типизированные операторы 
распределения памяти 

В языке программирования C++ для динамического размещения 
объекта  в  куче  используется  оператор 

new

,  который  имеет  сле-

дующий синтаксис: 

  new тип 

Здесь 

тип

  является  именем  встроенного  или  определенного  про-

граммистом типа данных. Например: 

  int* p; 
  p = new int;  // значение *p не определено 
  *p = 10;      // определяем значение *p 

Объект  можно  инициализировать  при  его  динамическом  созда-
нии. Для этого используется оператор 

new

 следующего вида: 

  new тип(выражение) 

Значение 

выражения

  задает  начальное  значение  объекта.  Напри-

мер: 

  int* p; 
  p = new int(10);  // *p = 10 


background image

Часть II. Язык программирования С++ 

144 

Для динамического удаления объектов из кучи используется опе-
ратор 

delete

, который имеет следующий синтаксис: 

  delete указатель 

Здесь 

указатель

  должен  указывать  на  объект,  предварительно 

распределенный оператором 

new

. Например: 

  delete p; 

Для  динамического  размещения  массива  объектов  в  куче  опера-
тор 

new

 имеет следующий синтаксис: 

  new тип[диапазон_1] ... [диапазон_n] 

Все  диапазоны,  за  исключением 

диапазона_1

,  должны  быть  кон-

стантами. Первый диапазон может быть переменной. Например: 

  int* p = new int[10];  // динамический массив 

Элементы динамически создаваемого массива нельзя проинициа-
лизировать. 
Для динамического удаления массива из кучи используется опе-
ратор 

delete

, который имеет следующий синтаксис: 

  delete[] указатель 

Указатель

  должен  указывать  на  массив,  предварительно  распре-

деленный оператором 

new[]

. Например: 

  delete[] p; 

Для динамического конструирования объекта в заданной области 
памяти  используется  оператор 

new

,  который  имеет  следующий 

синтаксис: 

  new(указатель) тип(значение) 

Этот  оператор  строит  объект  заданного 

типа

  в  области  памяти, 

адрес  которой  содержит 

указатель

.  Такая  форма  оператора 

new

 

называется 

оператором размещения

 

new

В  листинге  10.9  приведен  пример  конструирования  объектов  в 
заданной  области  памяти.  Естественно  в  этом  примере  можно 
было бы просто присвоить новые значения переменной 

n

. Но этот 

подход  не  годится,  когда  для  конструирования  объекта  нужно 
вызвать конструктор класса. 


background image

Глава 10. Дополнения к типам данных языка С 

145 

Листинг 10.9. Использование оператора размещения 

new

 

#include <iostream> 
using namespace std; 
 
int main() 

  int n; 
 
  int *p = new(&n) int(10); 
  cout << *p << ' ' << n << endl;  // 10 10 
 
  int *q = new(&n) int(20); 
  cout << *q << ' ' << n << endl;  // 20 20 
 
  return 0; 

По  стандарту  в  случае  ошибки  при  размещении  объекта  в  куче 
оператор 

new

  генерирует  исключение 

bad_alloc

.  Но  в  некоторых 

компиляторах  возможны  такие  реализации  этого  оператора,  ко-
торые  в  случае  невозможности  размещения  объекта  в  куче  воз-
вращают значение 

NULL

При  использовании  оператора 

delete

  нужно  учитывать  следую-

щие моменты. Во-первых, если операндом этого оператора явля-
ется пустой указатель, то оператор не выполняет никаких дейст-
вий. Во-вторых, если операндом этого оператора является непра-
вильный указатель, то поведение оператора непредсказуемо. 
Новые операторы распределения памяти имеют ассоциативность 
справа налево, а их приоритет совпадает с приоритетом унарных 
арифметических операторов. 

 

 


Смотрите также файлы