Операторы new и delete. Назначение. Синтаксис Пример.



В С++ появился более безопасный и удобный механизм выделения и освобождения памяти посредством операторов new и delete: указатель = new тип <(начальное значение)> <[кол-во элементов]>; delete указатель; или если был выделен массив, то delete [] указатель;

Если памяти недостаточно при выделении памяти, то либо new вернет нулевой указатель либо произойдет исключительная ситуация std::bad_alloc.

Операторы new и delete имеют преимущество перед стандартными функциями malloc(), free(). Во-первых, оператор new автоматически выделяет требуемое для хранения объекта количество памяти, т.е. не надо вызывать sizeof() для подсчета требуемого количества байтов. Во-вторых, оператор new автоматически вернет указатель нужного типа (malloc() возвращает указатель на void), т.е. не надо выполнять приведение типов. В-третьих, операторы new и delete можно перегружать: Начнем с оператора new – он имеет стандартный вид: void * operator new(size_t bytes) или void* operator new(size_t bytes, void* ptr). Параметр size_t должен быть в каждой перегруженной версии этого оператора, причем стоять должен на первом месте. Через этот параметр передается размер памяти в байтах, которую нужно выделить. Параметр ptr используется для передачи инициализирующего параметра, который указывается в скобках при вызове new: void* operator new(size_t bytes, Pool* pool) {      void* space = pool->next; pool->next += bytes; return space;} или void *operator new(size_t bytes){ void *p = malloc(size); if (!p) throw std::bad_alloc(); return p;} При вызове: A* a1 = new A; // Использует оператор new с одним параметром A* a2 = new (&localPool) Foo; // Использует оператор new c двумя параметрами

Оператор delete имеет две стандартные формы: void operator delete(void *address) и void operator delete(void *address, size_t bytes)

Пример: void operator delete(void *p) { if (p) free(p); return; }

Для перегрузки операторов new и delete, использующихся при выделении памяти под массивы используются специальные версии перегрузки: void * operator new[](size_t bytes), void* operator new[](size_t bytes, void* ptr), void operator delete[](void *address) и void operator delete[](void *address, size_t bytes). Кардинального отличия здесь нет, так как внутри оператора не выполняется какой-либо адаптации под работу с массивами, компилятор просто вызовет его столько раз сколько указано в квадратных скобках при вызове. Просто возможность отдельной перегрузки используется для явного указания: что при вызове с квадратными скобками надо вызвать этот оператор.


Операторы ввода-вывода в поток. Назначение. Синтаксис. Пример.

Система ВВ в С++, как и в С, может действовать через потоки. Поток ВВ – это логическое устройство, которое выдает и принимает пользовательскую информацию. Потоки свзяываются с визическим устройством посредством системы ВВ С++. Поскольку все потоки работают одинаково, то следовательно программист получает общий интерфейс работы с устройствами. При работе программ по умолчанию используются четрые потока cin (ввод с клавиатуры), cout (вывод на экран), cerr (вывод ошибки на экран), clog (буферизированная версия cerr). Для работы с потоком предусмотрено множество различных функций в модуле <iostream>, а также два оператора: оператор вставки << и оператор извлечения >>. Эти операторы в языке С++ можно перегрузить. Для перегрузки оператора вставки создается функция вставки, имеющая следующую форму: ostream& operator<<(ostream& stream, имя_класса& объект) {… return stream;}. Следует отметить одно важное обстоятельство: функция вставки не может быть членом того класса, для которого она перегружается. И вот почему. Если оператор является членом класса, то его левый операнд, который неявно передается при его вызове, передается через указатель this. Т.е. левый операнд должен быть объектом этого класса. Однако здесь эту роль выполняет поток вывода. Поэтому чтобы решить проблему доступа к внутренним членам класса при вызове этих функций вставки они часто объявляются как дружественные функции соответствующего класса.

Для перегрузки оператора извлечения >> создается функция извлечения, имеющая следующую форму: istream& operator>>(istream& stream, имя_класса& объект) {… return stream;}.


Дата добавления: 2018-04-15; просмотров: 378; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!