Классы. Базовый класс

Содержание

Слайд 2

Класс – это дальнейшее развитие понятия структуры. Он позволяет создавать новые

Класс – это дальнейшее развитие понятия структуры. Он позволяет создавать новые

типы и определять функции, манипулирующие с этими типами.
Объект - это представитель определенного класса.
ООП использует механизмы инкапсуляции, полиморфизма и наследования.
Слайд 3

Объединение данных с функциями их обработки в сочетании со скрытием ненужной

Объединение данных с функциями их обработки в сочетании со скрытием ненужной

для использования этих данных информации называется инкапсуляцией.
Наследование позволяет одному объекту наследовать свойства другого объекта, т.е. порожденный класс наследует свойства родительского класса и добавляет собственные свойства.
Полиморфизм - возможность использовать в различных классах иерархии одно имя для обозначения сходных по смыслу действий и гибко выбирать требуемое действие во время выполнения программы.
Слайд 4

Рассмотрим реализацию понятия даты с использованием структуры для того, чтобы определить

Рассмотрим реализацию понятия даты с использованием структуры для того, чтобы определить

представление даты date и множества функций для работы с переменными этого типа:
struct date
{
int month, day, year;
void set(int, int, int);
void get(int*, int*, int*);
void next();
void print();
};
Слайд 5

Класс является типом данных, определяемым пользователем. В классе задаются свойства и

Класс является типом данных, определяемым пользователем. В классе задаются свойства и

поведение какого-либо предмета или процесса в виде полей данных (аналогично структуре) и функций для работы с ними.
Описание класса
class <имя>{
[ private: ]
<описание скрытых элементов>
public:
<описание доступных элементов>
}; // Описание заканчивается точкой с запятой
Слайд 6

Поля класса могут быть простыми переменными любого типа, указателями, массивами и

Поля класса
могут быть простыми переменными любого типа, указателями, массивами и ссылками

(т.е. могут иметь практически любой тип, кроме типа этого же класса, но могут быть указателями или ссылками на этот класс);
могут быть константами (описаны с модификатором const ), при этом они инициализируются только один раз (с помощью конструктора) и не могут изменяться;
Инициализация полей при описании не допускается.
Слайд 7

class monster { int health, ammo; public: monster(int he = 100,

class monster
{
int health, ammo;
public:
monster(int he = 100, int am =

10)
{ health = he; ammo = am;}
void draw(int x, int y, int scale, int position);
int get_health(){return health;}
int get_ammo(){return ammo;}};
В этом классе два скрытых поля - health и ammo, получить значения которых извне можно с помощью методов get_health() и get_ammo().
Слайд 8

Методы класса имеют неограниченный непосредственный доступ к его полям. Внутри метода

Методы класса имеют неограниченный непосредственный доступ к его полям. Внутри метода

можно объявлять объекты, указатели и ссылки как своего, так и других классов.
В приведенном классе содержится три определения методов и одно объявление (метод draw ). Если тело метода определено внутри класса, он является встроенным (inline).
Слайд 9

В каждом классе есть метод, имя которого совпадает с именем класса.

В каждом классе есть метод, имя которого совпадает с именем класса.

Он называется конструктором и вызывается автоматически при создании объекта класса. Конструктор предназначен для инициализации объекта. Автоматический вызов конструктора позволяет избежать ошибок, связанных с использованием неинициализированных переменных.
Слайд 10

Описание объектов Конкретные переменные типа данных "класс" называются экземплярами класса, или

Описание объектов
Конкретные переменные типа данных "класс" называются экземплярами класса, или объектами.


monster Vasia; // Объект класса monster с параметрами по умолчанию
monster Super(200, 300);// Объект с явной инициализацией
monster stado[100]; // Массив объектов с параметрами по умолчанию
/* Динамический объект (второй параметр задается по умолчанию) */
monster *beavis = new monster (10);
monster &butthead = Vasia; // Ссылка на объект
Слайд 11

При создании каждого объекта выделяется память, достаточная для хранения всех его

При создании каждого объекта выделяется память, достаточная для хранения всех его

полей, и автоматически вызывается конструктор, выполняющий их инициализацию. Методы класса не тиражируются. При выходе объекта из области действия он уничтожается, при этом автоматически вызывается деструктор .
Слайд 12

Доступ к открытым ( public ) элементам объекта аналогичен доступу к

Доступ к открытым ( public ) элементам объекта аналогичен доступу к

полям структуры. Для этого используются операция . (точка) при обращении к элементу через имя объекта и операция -> при обращении через указатель.
Например:
int n = Vasia.get_ammo();
stado[5].draw;
cout << beavis->get_health();
Слайд 13

Наследование – возможность порождать новые классы на базе уже имеющихся с

Наследование – возможность порождать новые классы на базе уже имеющихся с

передачей порожденным классам наследства в виде данных и членов-функций родительского класса (или классов, если прямых родителей несколько).
Порожденные классы имеют возможность расширять набор данных, полученных по наследству, модифицировать родительские методы и функции, создавать новые данные и новые функции их обработки.
Слайд 14

Базовый и производный классы Принято называть родительский класс базовым, а вновь

Базовый и производный классы
Принято называть родительский класс базовым, а вновь созданный

класс – производным.
Механизм наследования ( inheritance ) предусматривает две возможности.
В первом случае, который называют простым наследованием, родительский класс один.
Во втором случае родителей два или больше, и соответствующий процесс именуют термином множественное наследование
Слайд 15

Простое наследование class D: [virtual][public|private|protected] B { тело производного класса };

Простое наследование
class D: [virtual][public|private|protected] B
{
тело производного класса
};
Чаще всего производный

класс конструируют по следующей схеме, которая носит название открытого наследования:
class D: public B {тело производного класса};
Слайд 16

Слайд 17

#include #include class B { int x; public: B(){x=0; cout B(int

#include
#include
class B {
int x;
public:
B(){x=0; cout<<"Def_B "< B(int

n){x=n; cout<<"Init_B "< B(const B &y){x=y.x; cout<<"Copy_B "< int get_x(){return x;}
~B(){cout<<"Destr_B"<};
Слайд 18

class D : public B { int y; public: D(){y=0; cout

class D : public B {
int y;
public:
D(){y=0; cout<<"Def_D "<

D(int n){y=n; cout<<"Init_D "< D(const D &z){y=z.y; cout<<"Copy_D "< int get_y(){return y;}
~D(){cout<<"Destr_D"<};
Слайд 19

void main() { B w1; cout B w2(2); cout B w3(w2);

void main()
{ B w1;
cout<<"w1.x="< B w2(2);
cout<<"w2.x="< B w3(w2);
cout<<"w3.x="<

B w4=w1;
cout<<"w4.x="< D q1;
cout<<"q1.x="<
Слайд 20

Динамическое создание и удаление объектов class A {...}; //объявление класса ..............

Динамическое создание и удаление объектов
class A {...}; //объявление класса
..............
A *ps=new A;

//объявление указателя и создание объекта типа A
A *pa=new A[20]; //объявление указателя и создание массива объектов
...............
delete ps; //удаление объекта по указателю ps
delete [] pa; //удаление массива объектов по указателю pa
Слайд 21

Создание одиночных объектов может быть совмещено с инициализацией объекта, если в

Создание одиночных объектов может быть совмещено с инициализацией объекта, если в

классе предусмотрен соответствующий конструктор:
A *ptr1=new A(5);//создание объекта и вызов конструктора инициализации
Массив создаваемых объектов проинициализировать таким же образом нельзя.
Слайд 22

Довольно распространенная ситуация, которая может оказаться потенциальным источником ошибок, возникает в

Довольно распространенная ситуация, которая может оказаться потенциальным источником ошибок, возникает в

процессе создания и удаления динамических объектов. Она заключается в том, что после уничтожения объекта, связанного, например, с указателем ps, этот указатель не чистится. Если после удаления объекта сделать попытку что-то прочитать или записать по этому указателю, то поведение программы предсказать трудно. Поэтому достаточно разумным правилом является засылка нуля в указатель разрушаемого объекта:
delete ps;
ps=NULL; //или ps=0;
Слайд 23

Виртуальные функции Виртуальными называют функции базового класса, которые могут быть переопределены

Виртуальные функции
Виртуальными называют функции базового класса, которые могут быть переопределены в

производном классе.
В базовом классе их заголовок начинается со служебного слова virtual.
Слайд 24

Рассмотрим пример, в котором базовый класс B содержит защищенное поле n

Рассмотрим пример, в котором базовый класс B содержит защищенное поле n

и отображает его содержимое на экране. Производный класс D1 отображает квадрат доставшегося по наследству поля. Еще один класс D2, порожденный тем же родителем B, отображает куб своего наследства.
#include
#include
class B {
public:
B(int k):n(k){} //конструктор инициализации
virtual void show(){cout<protected:
int n;
};
Слайд 25

class D1: public B { public: D1(int k):B(k){} // конструктор инициализации

class D1: public B {
public:
D1(int k):B(k){} // конструктор инициализации
virtual void

show(){cout<};
class D2: public B {
public:
D2(int k):B(k){} // конструктор инициализации
virtual void show(){cout<};
Слайд 26

void main() { B bb(2),*ptr; D1 dd1(2); D2 dd2(2); ptr=&bb; ptr->show(); ptr=&dd1; ptr->show(); ptr=&dd2; ptr->show(); }

void main()
{
B bb(2),*ptr;
D1 dd1(2);
D2 dd2(2);
ptr=&bb;
ptr->show();

ptr=&dd1;
ptr->show();
ptr=&dd2;
ptr->show();
}
Слайд 27

Чистые виртуальные функции и абстрактные классы Чистая виртуальная функция не совершает

Чистые виртуальные функции и абстрактные классы
Чистая виртуальная функция не совершает никаких

действий, и ее описание выглядит следующим образом:
virtual тип name_f(тип1 a1,тип2 a2,...)=0;
Класс, содержащий хотя бы одно объявление чистой виртуальной функции, называют абстрактным классом. Для такого класса невозможно создавать объекты, но он может служить базовым для других классов, в которых чистые виртуальные функции должны быть переопределены.
Слайд 28

Объявим абстрактным класс Shape (Геометрическая Фигура), в состав которого включим две

Объявим абстрактным класс Shape (Геометрическая Фигура), в состав которого включим две

чистые виртуальные функции – определение площади фигуры ( Get_Area ) и определение периметра фигуры ( Get_Perim ).
class Shape {
public:
Shape(){} //конструктор
virtual double Get_Area()=0;
virtual double Get_Perim()=0;
};
Слайд 29

class Rectangle: public Shape { double w,h; //ширина и высота public:

class Rectangle: public Shape {
double w,h; //ширина и высота
public:
Rectangle(double w1,double

h1):w(w1),h(h1) {}
double Get_Area() {return w*h;}
double Get_Perim() {return 2*w+2*h;}
};
class Circle: public Shape {
double r; //радиус
public:
Circle(double r1):r(r1) {}
double Get_Area() {return M_PI*r*r;}
double Get_Perim() {return 2*M_PI*r;}
};
Слайд 30

Если в производном классе хотя бы одна из чисто виртуальных функций

Если в производном классе хотя бы одна из чисто виртуальных функций

не переопределяется, то производный класс продолжает оставаться абстрактным и попытка создать объект (экземпляр класса) будет пресечена компилятором.
Слайд 31

Множественное наследование и виртуальные классы О множественном наследовании говорят в тех

Множественное наследование и виртуальные классы
О множественном наследовании говорят в тех случаях,

когда в создании производного класса участвуют два или более родителей:
class B1 {//первый базовый класс
int x;
public:
B1(int n):x(n) {cout<<"Init_B1"< int get_x(){return x;}
~B1() {cout<<"Destr_B1"<};
Слайд 32

class B2 {//второй базовый класс int y; public: B2(int n):y(n) {cout

class B2 {//второй базовый класс
int y;
public:
B2(int n):y(n) {cout<<"Init_B2"<

конструктор B2
int get_y(){return y;}
~B2() {cout<<"Destr_B2"<};
class D: public B1, public B2 {
int z;
public:
D(int a,int b,int c):B1(a),B2(b),z(c)
{cout<<"Init_D"< void show() {cout<<"x="<};
Слайд 33

#include void main() { D qq(1,2,3); qq.show(); } //=== Результат работы

#include
void main()
{
D qq(1,2,3);
qq.show();
}
//=== Результат работы ===
Init_B1
Init_B2
Init_D
x=1 y=2

z=3
Destr_D
Destr_B2
Destr_B1