Основы объектно-ориентированного программирования
Вопросы к Части 1
Парадигма ООП
Применимость ООП в конкретной предметной области
Определение базовых классов
Прототипное программирование
Инкапсуляция, контроль доступа. struct и class в С++
Контроль доступа при наследовании
Определение методов в C++
Определение методов в Delphi
Определение методов в C++ и Java. Inline - методы в C++
Механизм вызова виртуальных функций
Механизм вызова виртуальных функций
Множественные реализации
Друзья
Ссылка на себя (this, Self)
Ключевое слово const
Уточнение имени. inherited в Delphi
Вложенные классы
Указатели на методы
Инициализация и удаление
Инициализация: пример
Конструкторы
Деструкторы
Конструкторы и деструкторы: пример
Создание объектов
Конструкторы и деструкторы:
Выделение памяти для небольших объектов
471.00K
Категория: ПрограммированиеПрограммирование

Основы объектно-ориентированного программирования. Часть 2

1. Основы объектно-ориентированного программирования

Основы объектноориентированного
программирования
Часть 2

2. Вопросы к Части 1

Перечислите основные парадигмы
программирования
Перечислите основные понятия
ООП и дайте их определения

3. Парадигма ООП

Определите, какой класс вам
необходим
Предоставьте полный набор
операций для каждого класса
Общность классов выразите явно с
помощью наследования
ВОПРОС: Насколько оправдана
применимость ООП в конкретной
предметной области?

4. Применимость ООП в конкретной предметной области

Если общность между классами отсутствует,
вполне достаточно абстракции данных.
Применимость ООП для данной области
приложения определяется степенью
общности между разными типами, которая
позволяет использовать наследование и
виртуальные функции.
Примеры:
Интерактивная графика
Арифметические типы и вычисления над ними

5. Определение базовых классов

Нахождение общности среди отдельных типов
системы представляет собой нетривиальный
процесс. Степень такой общности зависит от
способа проектирования системы. В процессе
проектирования выявление общности классов
должно быть постоянной целью.
Она достигается двумя способами:
Проектированием специальных классов,
используемых как "кирпичи" при построении других
Поиском похожих классов для выделения их общей
части в один базовый класс.

6. Прототипное программирование

Стиль объектно-ориентированного
программирования, при котором
отсутствует понятие класса, а
повторное использование
(наследование) производится путём
клонирования существующего
экземпляра объекта — прототипа.
Два метода создания нового объекта:
клонирование существующего объекта,
либо создание объекта «с нуля».

7. Инкапсуляция, контроль доступа. struct и class в С++

class Stack {
private:
int *v,*p;
protected:
virtual int full();
int empty();
public:
virtual void push(int);
virtual int pop();
};
ВОПРОС: можно ли обойти этот способ
защиты данных?

8. Контроль доступа при наследовании

class A {
private:

protected:
int x;
public:
int y;
};
class B1: public A {
private:
protected:
public:
};
class B2: protected A {
private:
protected:
public:
};
class B3: private A {
private:
protected:
public:
};

9. Определение методов в C++

void Stack::push(int data)
{
if(!full())
*(p++)=data;
}

10. Определение методов в Delphi

procedure Stack.push(data: Integer);
begin
if(not full()) then
begin
v[Top]:=data;
Inc(Top);
end;
end;

11. Определение методов в C++ и Java. Inline - методы в C++

class Stack
{
public:
void push(int data)
{
if(!full())
v[Top++]=data;
}
int pop(); // реализация будет в другом месте
};
//…
inline int Stack::pop() { return v[--Top]; }

12. Механизм вызова виртуальных функций

class MyShape {
public:
virtual void draw ();
// ...
};
// ...
Circle c; Square s;
MyShape *p=&c;
if(some_condition) p = &s;
// точный тип p неизвестен
p->draw();

13. Механизм вызова виртуальных функций

Чтобы узнать, какую именно из функций rotate
следует вызвать, нужно до вызова получить
из объекта некоторую служебную
информацию, которая была помещена туда
при его создании.
Как только установлено, какую функцию надо
вызвать, допустим Сircle::rotate, происходит
ее вызов. Обычно в качестве служебной
информации используется таблица адресов
функций, а транслятор преобразует имя
rotate в индекс этой таблицы.

14. Множественные реализации

class ArrayStack: public Stack
{
int *v,p;
//…
};
class ListStack: public Stack
{
struct StackEntry
{ int data; StackEntry *next; } first;
//…
};

15. Друзья

class Matrix;
class Vector {
float v[4];
public:
friend Vector multiply(Matrix*, Vector*);
friend class Matrix;
virtual void put(float value, int index) { v[index] = value; }
};
//*******************************************
class Matrix {
Vector v[4];
public:
friend Vector multiply(Matrix*, Vector*);
};
Vector multiply(Matrix* a, Vector* b) { for(…) a->v[i].v[j] * b->v[k]; …. }

16. Ссылка на себя (this, Self)

class X
{
int m;
public:
readM(X* this) { return this->m; }
void writeM(X* this, int m) { this->m = m; }
};
X x; int y = x.readM(); -> y=X::readM(&x);
ВОПРОС: когда действительно нужен this?

17. Ключевое слово const

class X
{
int m;
public:
int read(const X* this) const { return m; }
void write(int i) { m = i; }
};
//…
void f(X* A, const X* B)
{ B->read(); B->write(1); …???… }

18. Уточнение имени. inherited в Delphi

class MyString {
char *s;
public:
virtual void strcat(char* s, char* s1)
{ ::strcat(MyString::s,::strcat(s,s1)); }
};
class HisString: public MyString {
void strcat(char* s, char* s1)
{ MyString::strcat(s,s1); }
};

19. Вложенные классы

class Set {
struct Element {
int mem; SetMem * next;
Element(int m, SetMem * n) { mem=m; next=n; }
};
Element * first;
public:
void set() { first=0; }
void insert(int m) { first = new Element (m,first); }
friend void f(Set* s);
};
void f(Set* s) {
Set::Element x; x.mem=5;
}

20. Указатели на методы

Объявление в С++
typedef void (MyClass::*MPtr)(int);
Использование в С++
MPtr m=&(MyClass::printInt);
MyClass x; (x.*m)(1);
Объявление в Delphi
type MPtr=procedure of MyClass(I:integer);
Использование в Delphi
MPtr m; m:=x.printInt; m(1);

21. Инициализация и удаление

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

22. Инициализация: пример

class vector {
public:
void init ( int size );
// вызвать перед первым использованием !!!!!
};
void f () {
vector v;
// пока v нельзя использовать
v.init ( 10 ); // теперь можно
} ВОПРОС: В чем опасность такой реализации?

23. Конструкторы

Будет лучше для инициализации переменных
определить некоторую специальную функцию.
Тогда две независимые операции
размещения и инициализации переменной
совмещаются в одной.
Функция инициализации называется
конструктором.
В С++ и Java конструктор имеет такое же имя,
как и сам класс.
В Delphi при определении используется
ключевое слово constructor
Конструкторов может быть несколько

24. Деструкторы

Если объекты некоторого типа строятся
нетривиально, то нужна еще одна
дополнительная операция для удаления их
после последнего использования.
Функция удаления называется деструктором.
В С++ деструктор имеет то же имя, что и его
класс, но перед ним стоит символ ~
В Delphi при определении используется
ключевое слово destructor
ВОПРОС: В какой момент вызывается
конструктор и деструктор?

25. Конструкторы и деструкторы: пример

class date {
int month, day, year;
public:
date(int, int, int); // день, месяц, год
date(int, int);
// день, месяц и текущий год
date(int);
// день и текущие год и месяц
date();
// по умолчанию: текущая дата
date(const char*); // дата как строка
~date();
};

26. Создание объектов

Объект может создаваться как:
автоматический, который создается каждый раз,
когда его
описание встречается при выполнении
программы, и уничтожается
по выходе из блока, в
котором он описан
статический, который создается один раз при запуске
программы
и уничтожается при ее завершении
объект в свободной памяти, который создается
операцией new и уничтожается операцией delete
объект-член, который создается в процессе создания
другого
класса или при создании массива,
элементом которого он является
если в выражении явно используется его конструктор

27. Конструкторы и деструкторы:

УПРАЖНЕНИЕ: Определить класс
Vector, динамически выделяющий
память (размер – параметр
конструктора) и освобождающий в
деструкторе
ВОПРОС 1: Как еще можно
использовать конструкторы и
деструкторы?
ВОПРОС 2: demo01

28. Выделение памяти для небольших объектов

struct Name {
char* string;
Name* next;
double value;
Name(char*, double, Name*);
~Name();
void* operator new(size_t);
void operator delete(void*, size_t);
};
УПРАЖНЕНИЕ: реализовать new и delete
English     Русский Правила