- •Чистые виртуальные функции и абстрактные классы
- •Производные классы с конструкторами и деструкторами
- •Виртуальные деструкторы
- •Обобщенный пример наследования
- •Модульность классов
- •Расширяющяся иерархия классов
- •Узловые классы
- •Множественное наследование классов
- •Шаблоны
- •Шаблоны функций
- •Перегрузка шаблонов функций
- •Шаблоны классов
- •Друзья Дружественные функции
- •Дружественные классы
- •Статические элементы класса
Модульность классов
Для разработки связанных наследованием классов целесообразно использование принципов модульного программирования, когда программа состоит из файлов заголовков, файлов отдельно компилируемых модулей, соединяемых в единое целое с помощью файла проекта программы.
Суть в том, что, имея встроенные элементы данных, методы и права доступа, класс обладает прирожденной модульностью. Поэтому при разработке программ следует выделять объявления каждого класса или группы взаимосвязанных классов в файл заголовков, с возможностью его дальнейшего расширения, либо добавления новых файлов заголовков при разработке новых классов. Описания невстроенных в класс методов при этом выделяются в другой файл (или файлы) реализации методов. После их компиляции образуются объектные файлы. Возможно группирование нескольких объектных файлов, содержащих классы, в библиотеку классов и расширение этой библиотеки. При этом алгоритмы методов остаются скрытыми, но они в объектной форме становятся доступными другим программистам. Последние могут использовать полученную библиотеку классов для разработки своих новых специализированных классов, не прибегая к исходному тексту программ.
Большая часть усилий по разработке приложений в С++ концентрируется на построении иерархии классов и трансформации полученного дерева наследования в код программы.
Размещение нескольких классов в одном модуле (файле)
Пример 41.
Рассмотрим разработку независимо компилируемого модуля, в состав которого входят классы Figure и Point на основе программы примера 40, то есть тела классов и функций должны быть скопированы из примера 40. Объявления этих двух классов поместим в файл "figures.h":
enum Boolean { false, true }; // булевы значения
class Figure // абстрактный базовый класс "фигура"
{ // тело класса Figure
};
// производный класс Point с открытым доступом к базовому классу Figure:
class Point: public Figure // класс "точка"
{ // тело класса Point
};
Этот процесс может продолжаться неопределенно долго – допускается определять другие производные классы от Figure, Point и т. д. Более того, как известно, допускается множественное наследование от более чем одного базового класса.
Определения всех невстроенных методов указанных двух классов образуют файл figpoint.cpp:
#include "figures.h" // подключение файла объявления классов
#include<graphics.h> // подключение библиотеки графики
#include<conio.h> // для функции getch()
// прототип обычной функции (не метод):
Boolean Getdelta (int& Deltax, int& Deltay);
// методы класса Point:
Point:: Point (int Initx, int Init): // конструктор класса Point
Figure (Initx, Inity) // передача аргументов базовому классу
{ Visible = false; // инициализация параметра Point
}
void Point:: Show() // метод изображения точки на экране
{ // тело метода Show
}
void Point:: Hide() // метод стирания точки с экрана
{ // тело метода Hide
}
void Point:: Moveto (int Newx, int Newy) // метод смещения точки
{ // тело метода Moveto
}
void Point::Drag(int Dragby) //метод перемещения точки с дискретом Dragby
{ // тело метода Drag
}
// обычная функция Getdelta:
Boolean Getdelta (int& Deltax, int& Deltay) // & - ссылки на смещение
{ // тело функции Getdelta
}
Рассмотрим головную программу, демонстрирующую возможности классов Figure и Point, которая сохраняется в файле, например, mainpoin.cpp:
#include "figures.h" // подключение файла объявления классов
#include<graphics.h> // подключение библиотеки графики
#include<conio.h> // для функции getch()
#include<iostream.h> // для ввода-вывода данных
#include<stdlib.h> // для функций random(), srand(), kbhit()
#include<dos.h> // для функции delay()
const char* path= "c:\\borlandc\\bgi"; // путь к bgi-библиотеке
void main() // главная функция:
{ // тело функции main
}
Создание проекта программы.
Для того чтобы разработать единую программу из нескольких разнотипных файлов, необходимо создать проект программы и откомпилировать его в среде BORLANDC3.1. Последовательность разработки проекта программы включает следующие этапы.
1. Создать папку (каталог), где будут размещаться все файлы проекта, например, под именем FIGPOINT.
2. Записать в папку проекта разработанные текстовые файлы (срр-файлы, h-файлы): figpoint.cpp, mainpoin.cpp, figures.h.
3. Выполнить команду меню Project-Open project. В окне Open-Project File перейти в поле Files и, начиная с нужного диска, найти свою папку. Перейти в поле Open-Project File, где вместо символа * набрать имя файла проекта, например, figpoint.prj и щелкнуть кнопку ОК. Внизу экрана появится окно Project:Figpoint с высвеченной строкой.
4. Выполнить команду меню Project-Add item. В окне Add item to Project List перейти в поле Files. Выделяя срр-файлы в любом порядке, кнопкой Add включить их в файл проекта и закрыть окно кнопкой Done.
5. Запустить файл проекта на компиляцию и выполнение командой Run-Run или клавишами <Ctrl-Enter>.
6. Выполнить отладку исходных файлов, выделяя в окне Project строку файла и нажав <Enter>.
7. После отладки проекта программы получить результаты работы exe-файла.
Проект программы может включать следующие файлы: 1) исходные срр-файлы; 2) файлы заголовков разработчика программы (h-файлы); 3) объектные obj-файлы; 4) файл проекта prj-файл; 5) исполняемый ехе-файл; 6) файл настройки среды dsk-файл, 7) копии файлов (bak-файлы).
