Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпора 130стр.doc
Скачиваний:
91
Добавлен:
15.06.2014
Размер:
2.49 Mб
Скачать

133

1) Абстрактный тип данных. Описание класса на языке C++. Классификация элементов класса.Модификаторы доступа к элементам класса.

Абстрактный тип охватывает 2 понятия - представление данных и операции, которые можно над этими данными совершить. Примеры абстрактных типов в С++ – массив, строка, очередь. Фундаментальная идея состоит в разделении несущественных деталей реализации подпрограммы и характеристик существенных для для корректного ее использования. Такое разделение может быть выражено через специальный "интерфейс":- множество функций, которые могут иметь доступ к структурам; - данных, посредством которых представлена "абстракция".

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

Абстрактный класс – класс, для которого программист НЕ НАМЕРЕН СОЗДАВАТЬ ОБЪЕКТЫ. НАЗНАЧЕНИЕ АБСТРАКТНОГО ТИПА ДАННЫХ – использование его В КАЧЕСТВЕ БАЗОВОГО ДЛЯ ПОСЛЕДУЮЩЕГО НАСЛЕДОВАНИЯ.

Класс делается АБСТРАКТНЫМ ТАК:Одна или более его функций объявляются ЧИСТО ВИРТУАЛЬНЫМИ: Т.Е. ТЕЛО ФУНКЦИИ ОПРЕДЕЛЕНО КАК 0 (ГОВОРЯТ, ЧТО ИНИЦИАЛИЗАТОР =0)

ПРИМЕР: virtual float do_comething() const=0;

МОЖНО ОБЪЯВЛЯТЬ УКАЗАТЕЛИ НА АБСТРАКТНЫЙ КЛАСС.

Конкретный класс – объекты которого можно реализовать.

Предназначение понятия класса состоит в том, чтобы предоставить программисту инструмент для создания новых типов, столь же удобных в обращении сколь и встроенные типы. В идеале тип, определяемый пользователем, способом использования не должен отличаться от встроенных типов, только способом создания. Тип есть конкретное представление некоторой концепции (понятия). Новый тип создается для того, чтобы дать специальное и конкретное определение понятия, которому ничто прямо и очевидно среди встроенных типов не отвечает. Хорошо выбранные типы, определяемые пользователем, делают программу более четкой и короткой. Это также позволяет компилятору обнаруживать недопустимые использования объектов, которые в противном случае останутся необнаруженными до тестирования программы. В определении нового типа основная идея - отделить несущественные подробности реализации (например, формат данных, которые используются для хранения объекта типа) от тех качеств, которые существенны для его правильного использования (например, полный список функций, которые имеют доступ к данным). Такое разделение можно описать так, что работа со структурой данных и внутренними административными подпрограммами осуществляется через специальный интерфейс (каналируется).

Абстракция данных в классе – это когда клиент класса не знает о реализации этого класса.(Клиент класса – это часть программы, которая пользуется этим классом).

Класс состоит из данных-элементов и функций-элементов. Данные элементы класса НЕ МОГУТ ПОЛУЧАТЬ НАЧАЛЬНЫЕ ЗНАЧЕНИЯ В ТЕЛЕ КЛАССА, ГДЕ ОНИ ОБЪЯВЛЯЮТСЯ ( А ТОЛЬКО ПРИ ПОМОЩИ КОНСТРУКТОРА)!

Доступ к объектам класса может ограничиваться набором функций, которые описаны как часть этого класса. Такие функции называются функциями членами или методами. ОНИ ВЫЗЫВАЮТСЯ В ОТВЕТ НА СООБЩЕНИЯ ПОСЫЛАЕМЫЕ ОБЪЕКТУ. Объекты класса создаются и инициализируются функциями членами, специально для этой цели описанными. Эти функции называются конструкторами. Функция член может быть специальным образом описана для "очистки" каждого классового объекта при его уничтожении. Такая функция называется деструктором. Чтобы использовать класс, необходимо создать объекты этого класса, и таких объектов можно создавать столько, сколько нужно.

РЕАЛИЗАЦИЯ КЛАССА - ЭТО ЗАКРЫТЫЕ ЭЛЕМЕНТЫ КЛАССА + ОПИСАНИЕ ОТКРЫТЫХ ФУНКЦИЙ-ЭЛЕМЕНТОВ.

Реализацию класса можно модифицировать не влияя на ее пользователей. ИМЕНА-СУЩЕСТВИТЕЛЬНЫЕ В ОПИСАНИИ СИСТЕМЫ ОТВЕЧАЮТ ЗА НАЛИЧИЕ КЛАССОВ.

ДОСТУП К ЭЛЕМЕНТАМ КЛАССА:

ОПЕРАЦИЯ ( . ) Обращается к элементу по имени переменной или по ссылке на объект.

ОПЕРАЦИЯ ( -> ) Доступ через указатель на объект. (имя_объекта->элемент эквивалентно (*имя_объекта).элемент).

Спецификаторы доступа:

class date {

int month, day, year;

public:

void set(int, int, int);

private:

int birthday;

protected:

};

Данные, объявленные после public и до следующего идентификаторадоступны при любом обращении программы к объекту. Метка public делит тело класса на две части. Имена в первой, закрытой части, могут использоваться только функциями членами. Вторая, открытая часть, составляет интерфейс к объекту класса.

Данные, объявленные после private и до следующего идентификаторадоступны ТОЛЬКО ФУНКЦИЯМ-ЧЛЕНАМ И ДРУЗЬЯМ КЛАССА. Это режим доступа к классу ПО УМОЛЧАНИЮ ( Т.Е. ЕСЛИ НЕТ ДРУГИХ СПЕЦИФИКАТОРОВ ДОСТУПА).Функции члены:Читают закрытые данные;Устанавливают значения закрытых данных;реализуют возможности класса;Вспомогательные

ОБЪЯВЛЯЕТСЯ специальным образом ( в теле класса). Если функция-член ОПИСЫВАЕТСЯ ВНЕ тела класса, то применяется БИНАРНАЯ ОПЕРАЦИЯ РАЗРЕШЕНИЯ ОБЛАСТИ ДЕЙСТВИЯ (:: )Она привязывает имя класса к имени элемента. Функции-члены имеют областью действия КЛАСС, НЕ-ЧЛЕНЫ – ФАЙЛ. Некоторые операции должны быть членами: конструкторы, деструкторы и виртуальные функции. Операция, изменяющее состояние объекта, должно быть членом, а не другом. Если нужно иметь неявное преобразование для всех операндов операции, то реализующая ее функция должна быть другом, а не членом.

Могут быть вызваны только для специальной переменной соответствующего типа с использованием стандартного синтаксиса для доступа к членам класса.

В функции члене на члены объекта, для которого она была вызвана, можно ссылаться непосредственно.

Конструктор. Функция конструирует значения данного типа, она называется конструктором. Конструктор распознается по тому, что имеет то же имя, что и сам класс.

КОНСТРУКТОР НИЧЕГО НЕ ВОЗВРАЩАЕТ Конструктор вызывается автоматически.

Когда класс имеет конструктор, все объекты этого класса будут инициализироваться. Если для конструктора нужны параметры, они должны даваться: date today = date(23,6,1983)

Часто бывает хорошо обеспечить несколько способов инициализации объекта класса. Такой подход необходим, если хочется предусмотреть все случаи использования класса. Это можно сделать, задав несколько конструкторов. Если конструкторы существенно различаются по типам своих параметров, то компилятор при каждом использовании может выбрать правильный.

Например:

class date {

int month, day, year;

public:

// ...

date(int, int, int); // день месяц год

date(char*); // дата в строковом представлении

date(int); // день, месяц и год сегодняшние

date(); // дата по умолчанию: сегодня

};Если у класса есть конструктор, то он вызывается всегда, когда создается

объект класса.

Объекты могут создаваться как:

[1] Автоматический объект: создается каждый раз, когда его описание

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

при выходе из блока, в котором оно появилось; Объект также может

быть сконструирован с помощью явного применения

конструктора в выражении, в этом случае он является автоматическим

объектом.

[2] Статический объект: создается один раз, при запуске программы, и

уничтожается один раз, при ее завершении;

[3] Объект в свободной памяти: создается с помощью операции new и

уничтожается с помощью операции delete;

[4] Объект член: как объект другого класса или как элемент вектора.

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

Деструктор необходим чтобы обеспечить соответствующую очистку объектов этого типа. Имя деструктора для класса X есть ~X() ("дополнение конструктора")

ДЕСТРУКТОР НИЧЕГО НЕ ПРИНИМАЕТ И НИЧЕГО НЕ ВОЗВРАЩАЕТ. Перегрузка деструктора не разрешается. Деструктор вызывается автоматически.

Inline – функции. Функция член, описанная (а не просто объявленная) в описании класса, считается inline.Inline нужен когда используется много маленьких функций. По сути, везде, где в программе традиционной структуры стояло бы просто какое-нибудь обычное использование структуры данных, дается функция. Это может страшно понизить эффективность, потому что стоимость вызова функции (хотя и вовсе не высокая по сравнению с другими языками) все равно намного выше, чем пара ссылок по памяти, необходимая для тела функции.Функции члены класса должны заново компилироваться всегда, когда вносится какое-либо изменение в описание класса.

Друзья Функция не может быть членом двух классов. Функция не член, получившая право доступа к закрытой части класса, называется другом класса (friend). Функция становится другом класса после описания как friend. Функция друг не имеет никаких особенностей, помимо права доступа к закрытой части класса. В частности, friend функция не имеет указателя this (если только она не является полноправным членом функцией). Описание friend - настоящее описание. Оно вводит имя функции в самой внешней области видимости программы и сопоставляется с другими описаниями этого имени. Описание друга может располагаться или в закрытой, или в открытой части описания класса; где именно, значения не имеет. Функция член одного класса может быть другом другого.

class matrix;

class vector {

float v[4];

// ...

friend vector multiply(matrix&, vector&);

};

class matrix {

vector v[4];

// ...

friend vector multiply(matrix&, vector&);

};

2) Виртуальная память

4-гигабайтное адресное пространство процесса фрагментировано. Программы и элементы данных разбросаны по адресному пространству блоками по 4 Кб, выровненных по границам, кратным 4 Кб. Каждый такой блок называется страницей (page) и может содержать либо код, либо данные. Когда страница действительно используется, она занимает физическую память, но программист никогда не встретится с физическими адресами. Микропроцессорный чип фирмы Intel эффективно преобразует 32-битный виртуальный адрес в номер физической страницы и смещение внутри нее, пользуясь двумя уровнями таблиц 4-килобайтных страниц. Отметим: отдельные страницы могут быть помечены либо как "только для чтения", либо как "для чтения и записи". Кроме того, у каждого процесса свой набор таблиц страниц. Регистр чипа CR3 содержит указатель на страницу каталога — переключаясь с одного процесса на другой, Windows просто обновляет этот регистр.

Страница памяти может быть отмечена в таблице страниц как "присутствующая",что говорит о том, что данная 4-килобайтная страница находится ли сейчас в памяти. При попытке обращения к странице, отсутствующей в памяти, генерируется прерывание, и Windows приступает к анализу ситуации, просматривая свои внутренние таблицы. Если обращение к памяти было неверным, выдается сообщение об ошибке страницы (page fault), и программа завершается. В ином случае Windows считает в оперативную память нужную страницу из дискового файла и обновит таблицу страниц, записав в нее физический адрес и установив бит присутствия. Таковы азы виртуальной памяти в Win32.

Момент чтения и записи страницы (чтобы достичь максимальной производительности) определяет диспетчер виртуальной памяти Windows. Если какой-то процесс не использовал страницу в течение определенного периода и эта память нужна другому процессу, данная страница выгружается из памяти, а вместо нее загружается страница нового процесса. Все процессы совместно используют один большой общесистемный файл подкачки (swap file), в который помещаются (при необходимости) все виды данных "для чтения и записи" и некоторые виды данных "только для чтения". (Windows NT поддерживает одновременную работу с несколькими файлами подкачки.) Windows определяет размер файла подкачки в зависимости от размера ОЗУ и свободного дискового пространства, но существуют способы тонкой настройки размера и физического расположения этого файла. Однако файл подкачки — не единственный файл, используемый диспетчером виртуальной памяти. Нет особого смысла в том, чтобы записывать в этот файл страницы кода. Вместо этого Windows проецирует ЕХЕ- и DLL-модули непосредственно на их дисковые файлы. Поскольку страницы кода помечены как "только для чтения", то необходимости в их записи обратно на диск не возникает. Если два процесса используют один и тот же ЕХЕ-файл, то данный файл отображается на адресные пространства обоих процессов. Файлы, проецируемые в память, о которых мы поговорим позже, также отображаются напрямую. Они доступны "для чтения и записи" и разделяются несколькими процессами.

Функции работы с виртуальной памятью:

Если программе нужна динамически распределяемая память, то рано или поздно ей придется вызвать функцию VirtualAlloc. Куча (heap) — это пул памяти какого-либо процесса. Когда программе требуется блок памяти, она вызывает функцию, выделяющую память из кучи, а чтобы освободить ранее выделенную память, — функцию, парную первой. Для выделения из нее памяти служит функция HeapAlloc, а для освобождения — функция HeapFree. HeapAlloc особенно удобна для выделения "крупных" блоков памяти. Обычно механизм виртуальной памяти позволяет операционной системе отображать несуществующую память в дисковый файл, называемый страничным файлом. Отображаемые в память файлы представляют естественное расширение механизма управления виртуальной памятью. Файловое отображение можно создать с помощью функции CreateFileMapping. Для открытия существующего отображения с определенным именем приложения могут использовать функцию OpenFileMapping. Функция MapViewOfFile отображает часть файла в блок виртуальной памяти.

Функции

• Резервирование региона в адресном пространстве

LPVOID VirtualAlloc(LFVOID IpAddress, DWORD cbSize, DWORD fdwAllocationType, DWORD fdwProtect)

• Возврат физической памяти и освобождение региона

BOOL VirtuaIFree(LPVOID IpAddress, DWORD cdSize, DWORD fdwFreeiype),

• Статус виртуальной памяти

VOID GlobalMemory Status(LPMEMORYSTATUS IpmstMemStat);

позволяет отслеживать текущее состояние памяти:

• В Win32 есть функция, позволяющая запрашивать определенную информацию об участке памяти по заданному адресу размер, тип памяти и атрибуты защиты

DWORD VirtualQueryCLPVOID IpAddress, PMEMORY_BASIC_INFORMATION IpBuffer, DWORD dw Length);