Similar presentations:
Лекция 12 Классы
1. Лекция 2.1. Классы
2. Основные элементы объектной модели
Концептуальной базой объектноориентированного стиля программированияявляется объектная модель, основывающаяся
на 4-х главных принципах:
Абстракция
Инкапсуляция
Модульность
Иерархия
2
3. Абстракция
• Выделяет существенные характеристикинекоторого объекта, отличающие его от других
видов объектов.
• Определяет концептуальные границы объекта с
точки зрения наблюдателя.
3
4. Инкапсуляция
• Отделяет друг отдруга элементы
объекта,
определяющие
его устройство и
поведения.
• Изолирует
внешний
интерфейс (то,
что нам нужно
знать для
работы с
объектом)от
внутренней
реализации.
4
5. Модульность
• Позволяет описать систему как наборкомпонентов с сильными внутренними
связями и более слабыми внешними
связями.
• Уменьшает сложность системы.
• Уровни модульности:
Файлы, каталоги…
Пространства имен, пакеты…
5
6. Иерархия
• Позволяет упорядочить абстракции,сформировать уровни абстрагирования,
определить способы взаимодействия
абстракций, их отношения.
6
7. Объектно-ориентированное программирование
ИнкапсуляцияНаследование
Полиморфизм
Классы объединяют данные
и методы их обработки,
ограничивая доступ для
различных категорий
пользователей
Создание новых классов на
основе существующих с
дополнением или изменением
их функциональности
Выполнение разных действий
одноименными методами
различных классов
Цель - повышение скорости разработки и качества программ
за счет лучшей структуризации и повторного использования
кода
7
8. Объектно-ориентированное программирование и C++
Язык С++ был разработан БьерномСтрауструпом в 1985 как расширение языка
С.
Бьерн Страуструп
Одним из основных принципов, лежащих в
основе С++, является его практически
полная совместимость с С, которая
существенно
облегчила
переход
программистов, работавших на языке С, к
объектно-ориентированному
программированию
и
гарантировала
применимость
разработанных
на С
программ.
Языки объектно-ориентированного программирования
C#, C++, Java, Delphi, Eiffel, Simula, D, Io, Objective-C, Object Pascal,
VB.NET, Visual DataFlex, Perl, Php, PowerBuilder, Python, Scala,
ActionScript, JavaScript, JScript.NET, Ruby, Smalltalk, Ada, Xbase++,
X++, Vala
8
9. Классы и структуры в C++
• Обеспечивают механизм создания собственныхтипов и определения различных действий над
ними.
• Обычно используются для описания
различных понятий, фигурирующих в
решаемой задаче.
• Акцентируют внимание разработчика на
моделировании данных, а не действий.
9
10. Классы
• Класс — это сущность, которая задает общиесвойства и общее поведение для объектов
(общий шаблон для создания объектов). По
сути класс является типом данных.
• Объект — это сущность в адресном
пространстве вычислительной системы,
которая появляется при создании экземпляра
класса и обладает определенным состоянием,
уникальностью и поведением.
10
11. Модель дороги с автомобилями
Объект «Машина»:свойства: координаты и скорость
P
V
X
• все машины одинаковы
• скорость постоянна
• на каждой полосе – одна машина
• если машина выходит за правую
границу дороги, вместо нее слева
появляется новая машина
Машина
X (координата)
P (полоса)
V (скорость)
двигаться
Метод – это процедура или функция,
принадлежащая классу объектов.
11
12. Класс: от требований к реализации
• Определить свойства рассматриваемойсущности, важные для данной задачи
• Определить основные действия
• Определить, какой набор данных
достаточен для описания этих свойств
• Определить список функций (методов),
соответствующих требуемым действиям
12
13. Инкапсуляция
КлассЗакрытая часть
if(parm->parm.getqinfoparm.gq_mask&IIAPI_GQ_ROW_COUNT)
putrowcount = parm->parm.getqinfoparm.gq_rowCount;
if(repeat and !query_hdl)
{
query_hdl = (unsigned int)parm->parm.getqinfoparm.
gq_repeatQueryHandle;
if(type == INPPAR)
{
if(itype == IIAPI_DTE_TYPE)
{
if(data->dtype() == _TTime)
DateUnixToIng(inp->date[inp->cnt],
(unsigned long)*(DTTime*)data);
if(data->dtype() == _TDate)
DTDateToIng(inp->date[inp->cnt], *(DTDate*)data);
}
if(RepeatQuery* r = FIND(repeatquery, query_id, query_id))
r->query_hdl = query_hdl;
else
{
repeatquery.New();
repeatquery.tmp.query_id = query_id;
repeatquery.tmp.query_hdl = query_hdl;
repeatquery.Modify();
}
StmtClose();
Query(NULL);
return(true);
if(itype == IIAPI_MNY_TYPE)
{
double d = *(DTMoney*)data;
long i = (long)d;
if(d-(double)i > 0.5) i++;
*(DTMoney*)data = (double)i;
}
if(itype == IIAPI_CHA_TYPE and repeat)
itype = IIAPI_VCH_TYPE;
}
DefPar(INPPAR, inp, inp->cnt++, itype, *data);
}
4
Интерфейс
Программа
13
6
14. Понятие класса в С++
КлассДанные
Методы
struct
Классы служат для объединения
данных и методов работы с ними в
новые типы данных.
Классы
могут
предоставлять
различные права доступа к данным
и методам.
Возможно
создание
иерархии
классов посредством наследования.
union
class Rectangle
{
int width;
int height;
int Square();
};
14
7
15. Ограничение доступа к элементам класса
КлассДанные + методы
Private
Данные + методы
Protected
Данные + методы
Public
Private - могут использоваться только
методами данного класса или дружественными
функциями.
class Example
{
int a;
int b;
protected:
int c;
public:
int d;
private:
int e;
public:
int f;
};
Protected - могут использоваться методами
данного и наследуемых классов.
Public - могут использоваться
функциями программы.
любыми
15
8
16. Уровни доступа к членам класса
Дляподдержки
принципа
инкапсуляции,
существуют
три
основных уровня доступа к членам
класса. Приведем их в порядке
открытости для внешних абстракций:
- Открытый(public) доступ – члены
с этим уровнем доступа видимы всем
клиентам класса.
- Защищенный(protected) доступ –
члены этого уровня видимы самому
классу,
его
подклассам,
и
абстракциям.
- Закрытый(private) доступ – члены
этого уровня видимы только изнутри
самого класса.
16
17. Открытый(public) доступ
1718. Защищенный(protected) доступ
1819. Защищенный(protected) доступ
1920. Закрытый(private) доступ
2021. Определение методов класса
В рамках класса (inline)Вне класса
class Rectangle
{
private:
int
w;
int
h;
public:
int
Square()
{
return(w*h);
}
};
class Rectangle
{
private:
int
w;
int
h;
public:
int
Square();
};
int Rectangle::Square()
{
return(w*h);
}
21
9
22. Доступ к элементам класса
class Rectangle{
public:
int
w;
int
h;
int
Square();
};
Через объект
Rectangle rect;
rect.w = 200;
rect.h = 100;
Через указатель на объект
Rectangle rect;
Rectangle *r = ▭
r->w = 200;
r->h = 100;
int s = rect.Square();
int s = r->Square();
22
23. Пример ограничения доступа к элементам класса
class Rectangle{
private:
int
w;
int
h;
public:
int
Square();
};
void main()
{
Rectangle r;
r.w = 100;
r.h = 50;
}
[C++ Error] test.cpp(50): E2247 'Rectangle::w' is not accessible
[C++ Error] test.cpp(51): E2247 'Rectangle::h' is not accessible
23
11
24. Конструкторы
Конструктор — это метод класса, который всегдавызывается при создании экземпляра класса
(объекта). Конструкторы предназначены для
создания объектов класса, и для инициализации
атрибутов объекта.
• Имя конструктора всегда совпадает с именем
класса.
• Конструктор может принимать параметры, но
никогда не возвращает значения.
• Класс может содержать несколько конструкторов
(перегрузка конструкторов).
• Если в классе не объявлен конструктор, то
компилятор предоставит конструктор по
умолчанию (стандартный конструктор).
• Стандартный конструктор не принимает
параметров и не выполняет никаких действий.
24
25. Специальный метод класса - конструктор
Специальный метод класса конструкторclass Rectangle
{
Конструктор
private:
int
w;
int
h;
public:
Rectangle(int Width, int Height);
int
Square();
};
Rectangle::Rectangle(int Width, int Height)
{
w = Width;
h = Height;
}
25
12
26. Конструкторы
Rational::Rational(){
std::cout << "Call the default constructor" << std::endl;
numer = 0;
denom = 1;
}
Rational::Rational(int n, int d)
{
std::cout << "Call constructor with parameters" << std::endl;
numer = n;
denom = d;
}
…
int main()
{
Rational r;
Rational r2(2, 3);
}
26
27. Перегрузка конструктора
class Rectangle{
private:
int
w;
int
h;
public:
Rectangle(int Width, int Height);
Rectangle(int Side);
int
Square();
};
Rectangle::Rectangle(int Side)
{
w = Side;
h = Side;
}
Перегруженный
конструктор
Rectangle::Rectangle(int Side)
{
Rectangle(Side, Side);
}
27
14
28. Конструктор копирования
специальный конструктор, применяемый для созданиянового объекта как копии уже существующего.
class Rectangle
{
private:
int
w;
int
h;
public:
Rectangle(int Width, int Height);
Rectangle(int Side);
Rectangle(Rectangle &R);
int
Square();
};
Rectangle::Rectangle(Rectangle &R)
{
w = R.w;
h = R.h;
}
Конструктор
копирования
28
15
29. Конструктор копирования Пример
2930. Конструктор копирования. Пример
3031. Создание объектов класса
Статическоеvoid func()
{
Rectangle r1(200, 100), r2(150), r3(r1);
...
}
Динамическое
void func()
{
Rectangle *r1 = new Rectangle(200, 100);
Rectangle *r2 = new Rectangle(150);
Rectangle *r3 = new Rectangle(*r1);
}
31
16
32. Деструкторы
Деструктор — это метод класса, который предназначендля уничтожения экземпляров класса, а также для
освобождения ресурсов используемых в объектах класса
(например, освобождение памяти).
• Деструктор не принимает параметров и не может
возвращать значение.
• Класс может иметь только один деструктор.
• Имя деструктора начинается символом «~»
• Деструкторы не могут перегружаться и наследоваться.
• Деструкторы могут описываться как виртуальные
(virtual)
• Деструкторы могут вызываться явно.
• Для класса без деструктора генерируется деструктор по
умолчанию(стандартный деструктор). Стандартный
деструктор не выполняет никаких действий.
• Деструктор всегда вызывается при выходе объекта за
пределы области видимости
32
33. Специальный метод класса - деструктор
Специальный метод класса деструкторclass Rectangle
{
private:
int
w;
int
h;
public:
Rectangle(int Width, int Height);
~Rectangle();
int
};
Square();
Деструктор
Rectangle::~Rectangle()
{
ShowMessage("Прямоугольник удален.");
}
33
17
34. Разрушение объектов класса
Статическоеvoid func()
{
Rectangle rect(200, 100);
...
}
Динамическое
void func()
{
Rectangle *rect = new Rectangle(200, 100);
...
delete rect;
}
34
19
35. Работа с памятью в конструкторах и деструкторах
class Array{
private:
int *data;
public:
Array(int Number);
~Array();
};
Array::Array(int Number)
{
data = new int[Number];
}
Array::~Array()
{
delete [] data;
}
35
20
36. Статические элементы класса
Статический элемент класса - это отдельно взятый член,являющийся глобальным в своем классе
Static int s_Total: //объявление статического элемента в
классе
int Critter::s_Total =О: // инициализация вне класса
• можно объявить статическую переменную (свойство класса) и в
свободных функциях (не относящихся к конкретному классу)
• статическое свойство сохраняет значение между отдельными
вызовами функций
• статическая функция-член (метод) является глобальной для всего
класса
• статический метод не может обращаться к нестатическим
свойствам, т.к. является глобальным в пределах класса и не
ассоциирован с каким-либо конкретным экземпляром этого
класса.
static int GetTotal() //прототип статического метода
36
21
37. Статические элементы класса. Пример
class Rectangle{
private:
int
w;
int
h;
static int count;
public:
Rectangle(int Width, int Height);
Rectangle(int Side);
Rectangle(Rectangle &R);
~Rectangle();
Статические данные
int
Square();
static int Count() { return(count); }
};
Статический метод
37
21
38. Использование статических элементов в методах класса
int Rectangle::count = 0;Rectangle::Rectangle(int Width, int Height)
{
int w = Width;
int h = Height;
count++;
}
Rectangle::~Rectangle()
{
count--;
}
38
22
39. Использование статических элементов класса
void main(){
Rectangle R1(200, 100);
Rectangle R2(150, 120);
Rectangle R3(160);
int c = Rectangle::Count();
ShowMessage(c);
}
R1
R2
R3
w
w
w
h
h
h
count
count
count
count
39
23
40. Указатель на текущий объект класса
Компилятор предоставляет каждому объектуclass Rectangle
указатель на него самого - this.
{
private:
Этот указатель может быть использован
int
w;
только внутри методов класса для получения
int
h;
адреса текущего объекта.
public:
Rectangle& Zoom(float Rate);
};
Rectangle& Rectangle::Zoom(float Rate)
{
w = (float)w*Rate;
h = (float)h*Rate;
return(*this);
}
Rectangle r(300, 200);
int s = r.Zoom(0.25).Square();
40
24
41. Указатель на текущий объект класса
void main(){
Rectangle R1(200, 100);
Rectangle R2(150, 120);
Rectangle R3(160);
R1.Zoom(2);
R2.Zoom(5);
R3.Zoom(0.5);
}
this
R1
R2
R3
w
w
w
h
h
h
41
25
42. Дружественные функции
Дружественнаяфункция — это
функция,
которая имеет
доступ к
закрытым
членам класса,
как если бы она
сама была
членом этого
класса.
Функция
может быть
другом сразу
для нескольких
классов
сlass Anything
{
private:
int m_value;
public:
Anything() { m_value = 0; }
void add(int value) { m_value += value; }
// Делаем функцию reset() дружественной классу Anything
friend void reset(Anything &anything);
};
// Функция reset() теперь является другом класса Anything
void reset(Anything &anything)
{
// И мы имеем доступ к закрытым членам объектов класса
Anything
anything.m_value = 0;
}
int main()
{
Anything one;
one.add(4); // добавляем 4 к m_value
reset(one); // сбрасываем m_value в 0
return 0;
}
42
43. Дружественные классы
class Values{private:
Если детали одного класса
int m_intValue;
изменятся, то детали класса-друга
double m_dValue;
также будут вынуждены
public:
Values(int intValue, double dValue)
измениться.
{
m_intValue = intValue;
m_dValue = dValue;
}
// Делаем класс Display другом класса Values
friend class Display;
1. Display не имеет прямого
};
доступа к указателю *this
объектов Values.
2. Values не является другом
Display
class Display
{
private:
bool m_displayIntFirst;
public:
Display(bool displayIntFirst) { m_displayIntFirst = displayIntFirst; }
void displayItem(Values &value)
{
if (m_displayIntFirst)
std::cout << value.m_intValue << " " << value.m_dValue << '\n';
else // или сначала выводим double
std::cout << value.m_dValue << " " << value.m_intValue << '\n';
}};
43
44. Дружественные методы
class Values; // предварительное объявление класса Valuesclass Display
{private:
bool m_displayIntFirst;
public:
Display(bool displayIntFirst) { m_displayIntFirst = displayIntFirst; }
void displayItem(Values &value); // предварительное объявление требуется для этой строки
};
class Values // полное определение класса Values
{private:
int m_intValue;
double m_dValue;
public:
Values(int intValue, double dValue)
{
m_intValue = intValue;
m_dValue = dValue;
}
friend void Display::displayItem(Values& value); // Делаем метод Display::displayItem() другом
класса Values
};
void Display::displayItem(Values &value)
{
if (m_displayIntFirst)
std::cout << value.m_intValue << " " << value.m_dValue << '\n';
else // или выводим сначала double
std::cout << value.m_dValue << " " << value.m_intValue << '\n';
}
44
45. Используемые ссылки
• https://ravesli.com/urok-154-bazovoe-nasledovanie-v-c/#toc-0• https://ravesli.com/urok-141-konstruktor-kopirovaniya/
• https://kpolyakov.spb.ru/school/ppt.htm#c
• https://ravesli.com/urok-121-skrytyj-ukazatel-this/
• Доусон М. Изучаем С++ через программирование игр. - СПб.:
Питер, 2016. - 352 с.: ил.
45
programming