ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4273
Скачиваний: 28
Глава 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
.
Часть 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; }
};
Глава 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
Часть 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
. Но этот
подход не годится, когда для конструирования объекта нужно
вызвать конструктор класса.
Глава 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
нужно учитывать следую-
щие моменты. Во-первых, если операндом этого оператора явля-
ется пустой указатель, то оператор не выполняет никаких дейст-
вий. Во-вторых, если операндом этого оператора является непра-
вильный указатель, то поведение оператора непредсказуемо.
Новые операторы распределения памяти имеют ассоциативность
справа налево, а их приоритет совпадает с приоритетом унарных
арифметических операторов.