- •Теоретические основы объектно-ориентированного программирования
- •Объектная декомпозиция
- •Диаграмма обслуживания автомашин на бензоколонке
- •Диаграмма объектов имитационной модели бензоколонки
- •Объектная декомпозиция Блока колонок: 1 - когда освободится колонка? 3 - колонка свободна? 2 - освободить колонку 4 - занять колонку
- •Диаграмма объектов графического редактора
- •Диаграмма состояний интерфейса пользователя программы «Записная книжка»
- •Диаграмма объектов предметной области программы «Записная книжка»
- •Обозначение ассоциации: а - с указанием имени ассоциации и ее направления; б - с указанием имен ролей; в - с указанием множественности
- •Контекстная диаграмма классов программы «Записная книжка»
- •Объекты и сообщения
- •Типы отношений между объектами
- •Соответствие объекта-абстракции классу и объектам-переменным
- •Основные средства разработки классов
- •Иерархии классов при различных видах наследования
- •Иерархия классов Окно и Окно_меняющее_цвет
- •Иерархия классов Окно и Окно_с_текстом
- •Иерархия классов при сложном полиморфизме
- •Необходимость позднего связывания
- •Реализация механизма позднего связывания
- •Необходимость явного указания типа объекта, адресуемого указателем родительского класса
- •Вид окна сообщения
- •Структура полей класса Сообщение
- •Дополнительные средства и приемы разработки классов
- •Организация стека вызовов
- •Определение класса
- •Организация списка объектов с использованием статических компонентов класса
- •Конструкторы и деструкторы
- •Наследование
- •Иерархия классов Целое число - Вещественное число
- •Диаграмма классов с наследованием от двух классов и объектным полем
- •Иерархия с многократным наследованием
- •Исключения
- •1. Динамическая проверка типа объекта:
- •2. Динамическое переопределение типа объекта:
- •3. Динамическое определение типа объекта:
-
Организация списка объектов с использованием статических компонентов класса
В поле first хранится адрес первого элемента списка, в поле last - адрес последнего элемента списка. Нестатическое поле next хранит адрес следующего объекта. Сформированный в примере список использован для вывода всех экземпляров класса с помощью статической функции drawAll(). Статическая функция drawAll() обращается к нестатическому полю next с указанием конкретного объекта:
#include <iostream.h>
#include <string,h>
#include <conio.h>
#include <alloc.h>
#include <stdio.h>
class String {
public: char str[40];
static String *first; // статическое поле - указатель на начало списка
static String *last; // статическое поле - указатель на конец списка
String *next;
String(char *s)
{ strcpy(str,s); next=NULL;
if(first==NULL)first=this; else last->next=this; last=this; }
void display() { cout <<str<<endl; }
static void displayAll(); // объявление статической функции
};
String *String::first=NULL; // инициализация статических компонентов
String *String::last=NULL;
void String::displayAll() // описание статической функции
{String *p=first;
if(p==NULL) return;
do {p->display(); p=p->next; } while (p!=NULL); }
void main(void) {
String а("Это пример"), b(''использования статических"), c(''компонентов");
// объявление-создание трех объектов класса
if (String::first !=NULL) // обращение к общему статическому полю
String:: displayAll(); // обращение к статической функции
getch();}
Использование статических компонентов класса позволяет снизить потребность в глобальных переменных, которые могли бы быть использованы с аналогичной целью.
Локальные и вложенные классы. Класс может быть объявлен внутри некоторой функции. Такой класс в C++ принято называть локальным. Функция, в которой объявлен локальный класс, не имеет непосредственного доступа к компонентам локального класса, доступ осуществляется с указанием имени объекта встроенного класса. Локальный класс не может иметь статических полей. Объект локального класса может быть создан только внутри функции, в области действия объявления класса. Все компонентные функции локального класса должны быть встраиваемыми.
Иногда возникает необходимость объявления одного класса внутри другого. Такой класс называется вложенным. Вложенный класс расположен в области действия класса, внутри которого он объявлен. Соответственно, объекты этого класса могут использоваться как компоненты внешнего класса. Компонентные функции и статические компоненты вложенного класса могут быть описаны вне глобального класса.
-
Вложенные классы. Пусть требуется разработать программу, которая рисует ломаную линию или многоугольник отрезками прямых, заданных координатами точек начала и конца отрезков.
#include <iostream.h>
#include <conio.h>
#include <graphics. h>
class Figura { // основной класс Фигура
class Point { // вложенный вспомогательный класс Точка
int x,y,cv;
public:
int getx() { return x;} // метод получения координаты
х int gety() {return y;} // метод получения координаты у
int getc() { return cv;} // метод получения цвета
void setpoint(int ncv) // метод задания координат точки и ее цвета
{ cout<<" введите координаты точки:"<<endl;
cin>>x>>y; cv=ncv;}
class Line { // вложенный вспомогательный класс Линия
Point Tn,Tk; // начало и конец линии
public:
void draw(void) // метод рисования линии
{ setcolor(Tn.getc());
line(Tn.getx(), Tn.gety(), Tk.getx(), Tk.gety());}
void setline(int ncv) // метод задания координат точек линии
{ cout«" введите координаты точек линии: "«endl;
Tn.setpoint(ncv); Tk.setpoint(ncv);}
void print() // метод вывода полей класса
{ cout«Tn.getx()«" "<<Tn.gety()<<" ";
cout<<Tk.getx()<<" "<<Tk.gety()<<endl; }
};
// продолжение описания класса Фигура
int kolline; // количество отрезков Фигуры
Line *mas; // динамический массив объектов типа Линия
public:
void setfigura(int n, int ncv); // прототип метода инициализации объекта
void draw(void); // прототип метода отрисовки линий
void delfigura() {delete [] mas;} // метод уничтожения полей объекта
void print(); // прототип метода вывода координат точек
};
void Figura::setfigura(int n, int ncv)
{ kolline=n;
cout<< " введите координаты "<<kolline« "линий: "<<endl;
mas=new Line [kolline];
for(int i=0;i<kolline;i++){mas[i].setline(ncv);} }
void Figura:: draw (void)
{ for(int i=0;i<kolline;i++) mas[i].draw();}
void Figura::print(void)
{ for (int i=0;i<kolline;i++) mas[i].print(); }
void main() { int dr=DETECT, mod; Figura Treangle;
initgraph(&dr, &mod, "с: \ \borlandc\\bgi");
cout << "результаты работы: "<<endl;
setbkcolor(15); setcolor(0);
Treangle.setfigura(3,6); // инициализировать поля объекта Треугольник
Treangle.print(); // вывести значения координат точек
getch();
setbkcolor(3); cleardevice();
Treangle.draw(); // нарисовать фигуру
Treangle.delfigura(); // освободить динамическую память
getch();}