Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++_шпоры(1).DOC
Скачиваний:
7
Добавлен:
08.08.2019
Размер:
200.19 Кб
Скачать

Ограничение при размещении массива

Массив нельзя инициализировать. Для освобождения динамически размещенного массива необходимо использовать следующую форму оператора delete: delete [] переменная_указатель;

Здесь квадратные скобки информируют оператор delete, что необходимо освободить память, выделенную для массива.

Пример выделения памяти для массива из 10 элементов типа float:

Элементам массива присваиваются значения от 100 до 109, а затем содержимое массива выводится на экран.

#include <iostream.h>

#include <except.h>

int main ()

float * p;

int i;

try {

p = new float [10]; //Получение десятого элемента массива

}

{catch (xalloc xa);

cout <<”Размещение не возможно\n”;

return 1;

}

{

//Присвоение значений от 100 до 109

for (i=0; i,10; i++) p[i] = 100.00 + i;

//Вывод содержимого массива

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

cout << p[i] <<” /n“;

delete []p; //Удаление всего массива

return 0;

}

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

Можно выделить память для любого типа данных. Сюда включаются и объекты.

Пример выделения памяти для объекта типа three_d:

#include <iostream.h>

#include <except.h>

class three_d {

public:

int x,y,z; //Трехмерные координаты

three_d (int a, int b, int c);

~three_d () {

cout <<”размещение\n”; }

};

three_d :: three_d (int a, int b, int c)

{ cout <<”Построение\n”;

x=a;

y=b;

z=c;

}

// Вывод координат x,y,z (оператор вставки для tree_d)

ostream & operator <<(ostream & stream, three d& obj)

{

stream <<obj.x <<” \n“;

stream <<obj.y <<” \n“;

stream <<obj.z <<” \n”;

returne stream; //Возврат потока

}

int main ()

{

three d*p;

try {

p = new three d(5,6,7);

}

catch (xalloc xa) {

cout <<”Allocation failure\n”;

return 1;

}

cout <<*p;

delete p;

return 0;

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

Первоначальный способ контроля за выделением памяти

В самом начале, когда язык С++ был изобретен, оператор new не игнорировал исключения и возникновения ошибки выделения памяти. Вместо этого он возвращал NULL аналогично функции malloc() языка С. Если необходимо, что бы оператор new работал таким образом вместо генерации исключения, просто надо вызвать функцию set new handler() с нулевым значением значением в качестве аргумента. После этого оператор new будет возвращать NULL, если он не сможет выделить запрашиваемую память. Кроме того, необходимо включить заголовочный файл new.h.

Пример альтернативного подхода к использованию new:

В программе вначале вызывается функция set new handler() с аргументом, равным нулю, а затем в цикле выделяется память до тех пор, пока не исчерпывается вся доступная для выделения память.

#include <new.h>

#include <iostream.h>

int main()

{

double * p; //new возвращает 0 в случае ошибки

set new handler (o); //Со временем память исчерпывается

do {

p=new double [100000];

if (p) cout <<”Allocation ok\n”;

else cout <<”Allocation Error\n”;

}

while (p);

return o;

}

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

Имеется возможность перегрузить new и delete. Это можно сделать в том случае, если необходимо использовать какой – то особый способ выделения памяти.

Процедура выделения памяти, автоматически использующая дисковый файл в качестве виртуальной памяти в том случае, когда «куча» оказывается исчерпываемой.

Формат перегрузки new и delete:

Void * operator new (size t размер)

{

//Выполнение выделения

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

}

void operator delete (void * p)

{

//Указатель *p }

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

Void * operator new[] (size t размер)

{

//Выполнение выделения

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

}

void operator delete[] (void * p)

{

//Освобождение памяти

}

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

Потоки ввода – вывода

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

Классы и потоки ввода – вывода

С++ обеспечивает поддержку системы ввода вывода в заголовочном файле <iostream.h>. В этом случае определены две иерархии классов, поддерживающие операции ввода – вывода. Основополагающим базовым классом является класс ios. Классом нижнего уровня в одной иерархий является streambuf. Этот класс обеспечивает базовые операции ввода – вывода. До тех пор, пока не вводятся свои собственные классы ввода – вывода, непосредственно streambuf не используются. Во второй иерархии классов класс ios обеспечивает поддержку форматированного ввода – вывода. От него порождены классы: istream, ostream, iostream.

Эти классы используются для создания потоков способных осуществлять ввод, вывод и ввод – вывод соответственно. От класса ios порождено много других классов. Классы могут специализироваться по направлению движения информации (ввод, вывод и ввод – вывод), по источнику информации и особенностям ее обработки (классы для файлового ввода – вывода, для строкового ввода – вывода, буферный и не буферный ввод – вывод, форматированный и не форматированный ввод – вывод). Класс ios содержит много функций – членов и переменных, которые управляют фундаментальными операциями с потоками. Включение файла <iosream.h> в программу, использующую средство ввода – вывода информации С++ обязательно. Использование в программе специализированных классов может потребовать включения файлов <fstram.h> и других. Функции – библиотеки ввода - вывода Borland C++ разбиты на 2 части: верхний уровень и нижний уровень. На своем нижнем уровне С++ интерпретирует любой файл, как последовательность (поток) байтов, имеющую начало и ограниченное концом файла. На этом уровне рассмотрения концепция типа данных со своими размерами исчезает. Библиотечные функции ввода – вывода нижнего уровня выполняют перенос этих байтов. С точки зрения прикладной программы, файл представляет собой произвольную последовательность символов, целых чисел, структурных переменных и т.д.

Библиотечные функции ввода – вывода верхнего уровня преобразуют данные, имеющие тип, в последовательность байтов и выполняют обратное преобразование. Для каждого типа перегружены два оператора: оператор извлечения из потока >> и оператор помещения в поток <<.

Замещающие функции способны воспринимать аргументы любых основных типов данных и могут быть расширены для того, что бы воспринимать

аргументы типа class. С каждым из потоков может быть связан параллельный поток. Параллельный поток – это поток, который определенным образом связан с исходным потоком. Например, он как – то обозначается, если начинается ввод в исходный поток.

Каждый поток хранит собственные установки форматирования, определяющие детали форматированного ввода – вывода. При выполнении ввода – вывода функции – члены базового класса ios отображают состояние выполняемой операции.

Пример функций – членов класса ios

Потоки стандартного ввода - вывода

Базовые операции ввода С++ поддерживаются специальным классом istream, а базовые рперации ввода классом ostream.

Вонаправленный ввод – вывод поддерживается классом iostream, являющимся производным от класса iostream и ostream.

Описание перечисленных классов приведены в файле <iostream.h>.

Есть 4 предоопределенных для пользования объекта (потока): cin, объект класса iostream, связанный со стандартным вводом; cout, объект класса ostream, связанный со стандартным вводом; cerr, объект класса ostream, выполняющий не буферизированный ввод в стандартный поток stderr; clong, объект класса ostream, выполняющий буферизированный вывод в стандартный поток stderr.

Т.к. cerr не буферизирован, то все, посланные в него данные выводятся немедленно. Противоположность этому clong буферизирован так, что данные выводятся только тогда, когда буфер оказывается полным. Операторы >> и <<, применяемые совместно с cin и cout выбирают необходимую информацию и функцию преобразования данных в поток байтов или обратного преобразования. При этом используются установки форматирования по умолчанию.

Функции – члены классов iostream и ostream позволяют выполнять дополнительное управление потоками.

Некоторые функции – члены класса ostream

Некоторые функции – члены класса iostream