русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Перегрузка new u delete


Дата добавления: 2013-12-23; просмотров: 1416; Нарушение авторских прав


Размещение объектов

Как отмечалось, можно выделить память для любого типа данных. Сюда включаются и объекты. Например, в следующей программе выделяет память для объекта класса point:

#include <iostream.h>

class point

{

int x, y, z;

public:

point(int a, int b, int c) { x=a; y=b; z=c; }

~point() { cout << "Destructing\n"; }

void show() { cout << x << “ “ << y << “ “ << z << “\n”; }

};

int main()

{

point *p;

set_new_handler(0);

p = new point(5, 6, 7);

if(!p) { cout << "Allocation failure.\n"; return 1; }

p->show();

delete p;

return 0;

}

Когда эта программа запускается, видно, что конструктор класса point вызывается в момент достижения строки, где стоит оператор new, а деструктор вызывается по достижении оператора delete. Заметим также, что инициализирующие значения автоматически передаются конструктору оператором new.

Ниже приведен пример, в котором размещается массив объектов типа point:

#include <iostream.h>

class point

{

int x, y, z;

public:

point(int a, int b, int c) { x=a; y=b; z=c; }

point() { cout << "Constructing\n"; }

~point() { cout << "Destructing\n"; }

void show() { cout << x << “ “ << y << “ “ << z << “\n”; }

void set(int a, int b, int c) { x=a; y=b; z=c; }

};

int main()

{

point *p;

int i;

set_new_handler(0);

p = new point[10];

if(!p) { cout << "Allocation failure.\n"; return 1; }

for(i=0; i<10; i++)

p[i].set(1, 2, 3);

for(i=0; i<10; i++)

p[i].show();

delete [] p;

return 0;

}

Обратим внимание, что к классу point добавлен второй конструктор. Поскольку динамический массив не может быть инициализирован, то требуется конструктор без параметров. Если такой конструктор не будет определен, то компилятор выдаст сообщение об ошибке.



Имеется возможность перегрузить операторы new и delete. Это следует делать в том случае, если необходи­мо использовать какой-то особый способ выделения памяти. Например, может понадобиться процедура выделения памяти, автоматически использующая дисковый файл в качестве виртуаль­ной памяти в том случае, когда куча оказывается исчерпанной. Какой бы ни была причина, осуществить такую перегрузку очень просто.

Для перегрузки операторов new и delete может использоваться следующий формат:

void* operator new(size_t размер)

{

// выполнение выделения памяти

return указатель_на_память;

}

void operator delete(void *p)

{

// освобождение памяти, на которую указывает р

}

Параметр размер будет содержать число в байтах, которое необходимо выделить для размещения объекта. Это значение будет сформировано автоматически. Перегруженная функция new должна возвращать указатель на выделенную память. За исключением этих ограничений перегруженная функция new может выполнять все, что необходимо.

Функция delete получает указатель на область памяти, которую необходимо освободить. Она обязана освободить эту память. Для перегрузки операторов new и delete применительно к масси­вам надо использовать следующий формат:

void* operator new[](size_t размер)

{

// выполнение выделения памяти

return указатель_на_памятъ;

}

void operator delete[](void *p)

{

// освобождение памяти, на которую указывает p

}

Можно перегрузить операторы new и delete глобально или относительно класса. Для того что­бы перегрузить их по отношению к классу, просто надо сделать их функциями-членами этого класса.

Глава 7. Библиотека классов ввода/вывода С++

C++ поддерживает все функции ввода/вывода языка С и, кроме того, определяет свою собствен­ную объектно-ориентированную систему ввода/вывода. В этой главе дается обзор библиотеки классов ввода/вывода языка C++. Также описывается, каким образом можно перегрузить операторы << и >> так, чтобы выводить собственные объекты. Система ввода/вывода C++ очень велика, и мы не можем охватить ее здесь всю целиком. Однако в этой главе будут рассмотрены наиболее важные и широко используемые функции и особенности этой системы ввода/вывода.

7.1 Почему C++ имеет свою собственную систему ввода/вывода

Система ввода/вывода языка С — одна из самых мощных и гибких среди всех языков программирования. Но несмотря на мощь функций ввода/вывода С, эта система не обеспечивает поддержки объектов, определенных пользователем. Это является одной из причин, почему в языке C++ опре­делена своя система функций ввода/вывода. Например, если на языке С создать структуру:

struct my_struct

{

int count;

char s[80];

double balance;

};

то невозможно приспособить или расширить систему ввода/вывода языка С таким образом, что­бы она могла непосредственно осуществлять ввод/вывод переменных типа my_struct. Используя подход C++ к вводу/выводу, можно перегрузить операторы << и >> таким образом, чтобы они знали, как работать с созданными программистом классами.

Хотя системы ввода/вывода С и C++ содержат фактически одинаковые операторы, тот факт, что система C++ может работать с определенными пользователем типами, неизмеримо повышает гибкость ввода/вывода. Такой подход также помогает предотвратить возникновение ошибок. Например, в следующем вызове функции scanf():

char str[80];

int i;

scanf("%d%s", str, &i);

стоящие в списке аргументов строка и целое число поменялись местами, так что %d соответствует строке str, a %s соответствует целому числу i. Такой вызов не порождает ошибки в языке С, хотя и выдает неверный результат. Тем не менее, такой вызов функции scanf() является ошибочным. По сути, при вызове функции scanf() в С не осуществляется строгой проверки типов. В противоположность этому, в C++ операции ввода/вывода для всех встроенных типов определены относительно операторов << и >>, так что возможности возникновения подобной ошибки в нем нет. Вместо этого автоматически будет вызвана корректная операция, которая определяется типом операнда. Эти черты ввода/вывода C++ имеют место также и для определенных пользователем объектов.



<== предыдущая лекция | следующая лекция ==>
Работа с памятью с помощью new и delete | Создание собственных операторов вставки и извлечения


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.004 сек.