Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 [ 44 ] 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

> Рекомендация

Следует четко представлять, к каким реальным расходам памяти приводит использование различных видов контейнеров и стратегии распределения динамической памяти.



Задача 22, Новый взгляд на new.

Часть 1: многоликий оператор new Сложность: 4

Любой класс, предоставляющий собственный оператор new или new[], должен также обеспечить соответствующие версии обычного оператора new, размещающего new и new, не генерирующего исключений. В противном случае у пользователей вашего класса могут возникнуть ненужные проблемы.

Вопрос ДЛЯ новичка

1. Какие три варианта оператора new описаны в стандарте С++? Вопрос для профессионала

2. Что такое оператор new, специфичный для класса, и как им следует пользоваться? Опишите, в каких случаях вы должны быть особо осторожны при предоставлении собственных, специфичных для класса операторов new и delete.

3. Какой именно оператор new вызывается в приведенном далее коде в строках, пронумерованных от 1 до 4?

class Base { public:

static void* operator new(std::si2e t, const FastMemoryA);

class Derived : public Base {

...

Derived* pl = new Derived; 1

Derived* p2 = new (std::nothrow) Derived; 2

void* p3 = /* некоторая область памяти, достаточная

для размещения Derived */ ; new (рЗ) Derived; 3

FastMemory f;

Derived* p4 = new (f) Derived; 4

Решение

в этой и следующей задачах я хочу сформулировать и обосновать два основных совета.

• Любой класс, предоставляющий собствснный оператор new или new[], должен также обеспечить соответствующие версии обычного оператора new, размещающего new и new, не генерирующего исключений. В противном случае у пользователей вашего класса могут возникнуть ненужные проблемы.

• Избегайте использования new(nothrow) и убедитесь, что, когда вы проверяете отказ new, вы действительно проверяете именно то, что хотите проверить.

Советы могут показаться неожиданными, поэтому давайте детально их проанализируем. Для простоты я не упоминаю отдельно оператор new для массивов, но все сказанное об операторе new для одного объекта, относится и к нему.



Размещающий, обычный и не генерирующий исключений оператор new 1. Какие три варианта оператора new описаны в стандарте С++?

В стандарте С++ описаны три варианта оператора new и разрешено произвольное количество дополнительных перегрузок.

Одним полезным видом этого оператора является размещающий new, который строит объект в имеющейся области памяти, без выделения нового пространства. Например:

пример 22-1(а): использование размещающего new

выделение достаточного количества памяти void* р = ::operator new( sizeof(Т) );

new(p)T; создание объекта Т по адресу р, вероятно, вызовом ::operator new(std::size t, void*) throwQ

Стандарт также предоставляет "обычный старый new", который не получает никаких дополнительных параметров и не генерирует исключений (nothrow new). И иже представлен полный список перегруженных операторов new из стандарта С+ + .

перегрузки оператора new в стандарте языка (имеются соответствующие версии и для new[]):

void* ::operator new(std::size .t size) throw(std::bad alloc); обычный старый оператор new Использование: new т

void* ::operator

new(std::size t size, const std::nothrow t&) throwC); Оператор new, не генерирующий исключений использование: new (std::nothrow) т

void* ::operator new(std::size t size, void* Размещающий оператор new использование: new (ptr) T

ptr) throwO;

Программа может заменить все, кроме последнего, операторы new на свои собственные версии. Все эти стандартные функции находятся в глобальной области действия, а не в пространстве имен std. Табл. 22.1 дает краткие характеристики стандартных версий new.

Таблица 22.1. Сравнение стандартных версий оператора new

Версия new

Дополнительный параметр

Вьшеленис памяти

Воз.можность сбоя"

Генерация

исключений

Замещае-

мость

Обычный

(генерирует

исключение)

std::bad a Hoc

генерирующий исключений

std::nothrow t

(возвращает

Размещающий

voi d*

После выгюлнения оператора new вызывается конструктор объекта, и, конечно, этот конструктор может вызвать сбой -- но в данном случае нас это не волнует. Сейчас нас интересует только вопрос о сбое в самом операторе new.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 [ 44 ] 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85