- •Курс лекций по объектно-ориентированному программированию
- •1. Введение. Объектно-ориентированное программирование как технология программирования. (4 час.)
- •Объектная модель
- •2. Расширение языка с. ( 3 час.)
- •Тип_функции имя_функции (спецификация_формальных_параметров);
- •Int infunc(float, int); // Прототип функции
- •3. Классы. (3 час.)
- •Int day; // день
- •Int month;
- •Int month;
- •Int month;
- •Int year;
- •Int month;
- •Int year;
- •Int *month;
- •Int *year;
- •Int size;
- •Int readm() { return m; };
- •Void f()
- •X *this;
- •Int day,month,year;
- •Void main()
- •Void shedule(int);
- •Void wait(event);
- •Void main()
- •Void strange(int I)
- •Void f()
- •Int check(char t, char* s)
- •Void f()
- •Void dat::put() const
- •X *Object_x;
- •Int X; // Личная часть класса
- •Void fun2(a&);
- •Void fun(a&);
- •Void f(complex a, complex b)
- •X* operator&(); // унарное & (взятие адреса)
- •X operator&(X); // бинарное & (операция и)
- •X operator&(X,X); // ошибка: тернарное
- •Int month;
- •Int year;
- •Void next(); // Элемент-функция вычисления следующего дня
- •Void dat::next()
- •Void main()
- •Void main()
- •Int size;
- •Int size; // Длина строки
- •Int operator[](char*); // Операция поиска подстроки
- •Int n; // целое
- •Void display () //вывод значения
- •Void main()
- •Void* operator new(size_t size);
- •Void operator delete (void *);
- •Int month;
- •Int year;
- •Void main()
- •Int month;
- •Int year;
- •Int r; // Текущий результат
- •Int I; // Счетчик месяцев
- •Void main()
- •Void g()
- •1.M(); // ошибка
- •Void g();
- •Void f(),
- •Void funс (int I)
- •Void funс (int I)
- •Void main(void) {
- •Virtual void vfunc (int I)
- •Void vfunc (int I)
- •Void vfunc (int I)
- •Void main(void)
- •Void main(void)
- •Virtual int f(int j) { return j * j; };
- •Int f(int I) { return base::f (I * 2); };
- •Void s(int);
- •Void f (int);
- •Void s (int);
- •Int line;
- •Int y_or_n(ostream& to, istream& from)
- •If (!cin.Get(ch)) return 0;
- •Void error(char* s, char* s2)
- •Istream from(&f1);
- •If (!from.Eof() && to.Bad())
- •7. Параметризованные типы и функции. (2 час.)
- •Void swap (t* X, t* y)
- •Void swap(long* X, long* y)
- •Void swap(double* X, double* y)
- •Void main()
- •Void main()
- •Void main()
- •Int size; // Количество элементов в иассиве
- •Vector (int); // Конструктор класса vector
- •Void main()
- •Int length;
- •Void main()
Void dat::put() const
{ ... }
Аналогично можно определить константные объекты:
const class a {...} value;
Контейнерные классы. Реализация событийного управления. Класс Y называется контейнерным по отношению к классу X, если объект или массив объектов класса Y являются данными-членами класса X. При этом можно говорить, что объект класса X и объект(ы) класса Y находятся в отношении «включает в себя», а объект(ы) класса Y «входи(я)т» в объект класса X. Указанные отношения объектов классов X и Y существенно отличаются от отношения «является», так как объекты этих классов могут не иметь общих свойств. Будем различать два вида реализации контейнерных классов:
объекты класса X являются владельцами контейнерных объектов класса Y,
объекты класса Y являются самостоятельными объектами, включаемыми в объекты класса Х в качестве контейнерных.
В первом случае (X владеет Y) возможны 2 реализации:
class X { class Y {
... ...
Y Object_Y; Y(void);
... ...
}; };
Особенности первой реализации состоят в том, что
так как Object_Y представлен в классе X как объект, то нет необходимости управлять его созданием в конструкторах и уничтожением в деструкторах класса X,
в классе Y обязательно наличие контструктора без параметров или вообще отсутствие конструктора (используется конструктор по умолчанию),
для заполнения свойств контейнерного объекта Object_Y в классе Y должны присутствовать соответствующие методы, доступные классу X.
class X { class Y { ... };
...
Y *Object_Y;
...
X(...) { ...; Object_Y = new Y; ...; };
~X() { ...; delete Object_Y; ...; };
...
};
Особенности второй реализации состоят в том, что
так как Object_Y представлен в классе X как указатель на объект класса Y, то при создании объекта X, сам контейнерный объект не создается. Конструкторы класса X должны вызывать нужный конструктор контейнерного объекта, а деструктор – уничтожать.
для изменения свойств контейнерного объекта по указателю Object_Y в классе Y должны по-прежнему присутствовать соответствующие методы, доступные классу X.
Во втором случае (Y самостоятельный объект) объекты класса X не должны никаким образом управлять процессами создания и уничтожения контейнерных объектов, поэтому реализация контейнерной связи может быть только с использованием указателей.
class X { class Y { ... };
...
Y *Object_Y;
void AddY(Y* y) { ...; Object_Y = y; ...; };
...
};
X x;
Y y;
x.Add(&y);
В классе X при этом должен существовать открытый метод установки связи между самостоятельными объектами классов X и Y.
Пусть некоторое событие в объекте класса X, под которым мы понимаем любое изменение свойств объекта, влечет за собой событие в контейнерном объекте класса Y. При любой реализации контейнерной связи генерация события в классе Y является тривиальной, так как объекты X знают об связанных с ними объектах Y. Достаточно лишь наличие в классе Y метода, реализующего это событие, доступного из метода в классе X, инициирующего это событие через контейнерный объект класса Y, описанного в классе X.
в классе X: в классе Y:
Event_X: Event_Y(...)
Object_Y.Event_Y(параметры события)
или
Object_Y->Event_Y(параметры события)
Больший интерес представляет случай, когда инициатором события является контейнерный объект класса Y, при котором изменяются свойства объекта-контейнера класса X. Для случая независимой реализации объектов, решение данной задачи заключается в том, что данные-члены обоих классов теперь должны включать взаимные ссылки классов в виде указателей.
class X;
class Y {
...