Лекции_Классы
.pdfРеализация Фун перегрузки Оп =
Vector Vector :: operator =( Vector t )
{x = t.x; y = t.y; z = t.z;
return *this;
}
// А = В;
Реализация Фун перегрузки Оп +=
Vector Vector::operator +=( Vector t )
{x += t.x; y += t.y; z += t.z;
|
return *this; |
} |
// А += В; |
// Об слева (A) - Рез-т |
Реализация Фун перегрузки Оп ++Ob, Ob++
Vector Vector::operator ++(void)
{ x++; y++; z++; return *this; } Vector Vector::operator ++( int )
{Vector tmp;
tmp = *this; // возврат предыдущего знач-я
x++; |
y++; |
z++; |
return tmp; |
// Постфиксная ++ |
}
21
Использование перегруженных Оп
main( )
{ Vector A(1, 2, 3), B(10, 20, 30), C;
C = A + B; |
// C = 11, 22, 33 |
C = A + B + C; |
// C = 22, 44, 66 |
C = A = B; |
// C = A = 10, 20, 30 |
А += В; |
// A = 20, 40, 60 |
}
Правила перегрузки Операций
Не перегружаются: . .* :: ?= sizeof ;
Перегружать можно только существ-е Оп в С++ ;
Старшинство Оп перегрузкой не изменяется;
Изменить кол-во операндов Операций нельзя;
Нельзя изменить работу Оп с Об типов Д С++: (int, float, . . . );
Ук this используется только для Фун-Эл Класса;
() [ ] -> = можно перегрузить только Фун-Эл Класса;
При перегрузке унарных Оп Фун-Элементом Класса не треб-ся аргументов
( ++Оb );
Перегрузка Оп [ ] индексации рассм-ся как бинарная: 1-ый Операнд – Об Класса, 2-ой – индекс;
Для перегрузки Оп можно использовать дружественные Фун
Дружественные функции
-имеют доступ к закрытой и защищённой частям Класса, не являясь Фун – эл-ми этого Класса. Это внешняя Фун.
class X
{
. . . friend_fun( )
}
22
Дружественные функции
сlass С1; //предварительное объявление Класса
сlass C2;
{ int s; |
// Класс С2 доверяет |
public: |
|
friend int |
frd( C1 ob1, C2 ob2 ); |
. . . . . |
|
}; |
|
class C1 |
|
{ int s; |
// Класс С1 доверяет |
public: |
|
friend int |
frd( C1 ob1, C2 ob2 ); |
. . . . . |
|
}; |
|
// Пример дружественной Функции: int frd( C1 ob1, C2 ob2 )
{ if (ob1.s == ob2.s) return 1; return 0;
}
Дружественной Фун может быть Фун-эл другого Класса.
Для примера выше пусть в Классе C1 имеется описание Фун
public: |
int frnd( C2 ob2 ); |
class C2
{int s; public:
friend int C1 :: frnd( C2 );
};
Дружественные классы
При объявлении Класса сразу можно объявить
все Фун-Эл другого Класса дружественными данному Классу.
Пример: сlass X
{ . . . . . };
23
сlass Y
{. . . . .
friend class X;
. . . . .
};
Перегрузка Оп << - вставка в Поток
только через друж-ю Фун !
ostream &operator << (ostream &stream, Vector t)
{ stream <<” “ << t.x <<” “ <<t.y <<” “<<t.z; return stream;
}// Д.б. в классе Vector как друж-я
сlass Vector // Пример
{ public:
Vector( int xx, int yy, int zz); // К-р
Vector operator + ( Vector t );
Vector operator = ( Vector t );
friend ostream &operator << (ostream &stream, Vector t);
private: int x, y, z;
};
Пример: Перегрузка Оп <<
. . . . .
void main() |
|
{ Vector t(1, 2, 3); |
// t = (1, 2, 3); |
cout << t; |
// На экране: 1 2 3 |
. . . . . |
|
}
Правила перегрузки Оп с использ-ем Друж-х Фун
• |
Друж_Фун нельзя перегрузить Оп: = ( ) [ ] -> , |
• |
Для Друж_Фун не исп-ся Ук this, |
|
24 |
•Друж_Фун следует передавать:
-два аргумента для бинарной Оп,
-один аргумент для унарной Оп
***ПиОА_Л10 *** Классы 4
Цель: понять композицию в классах, концепцию ООП-я полиморфизм и
механизм Виртуальных Функций (ВиртФун), Шаблоны Фун и Классов.
Содержание:
•Композиция: Классы как Эл-ты других Классов;
•Полиморфизм, Виртуальные Функции;
•Абстрактные Классы
•Шаблоны Фун и Классов
Композиция: Классы как Эл-ты других Классов
// Пример: сведения о служащем содержат дату
class Date
{ public:
Date (int = 1, int = 1, int = 1900); void out();
private:
int m, d, y;
…
};
// Конструктор
Date::Date (int mn, int dy, int yr) { if( mn > 0 && mn <= 12 )
m = mn;
else { < Предупр-е об ошибке > }
d = dy; // Проверка правильности dy y = yr; // Проверка правильности yr
}
25
сlass Emp
{ public:
Emp (char *, int, int, int, int, int, int); void print(); //сведения о служащем
private:
char name[40]; // имя служащего
Date bDate; // дата рождения
Date hDate; // дата приёма на работу
};
Emp::Emp( char *name_emp, int bm, int bd, int by,
int hm, int hd, int hy ):
bDate( bm, bd, by ), // Передача арг-в hDate( hm, hd, hy ) // К-рам Об-в
{ int len = strlen(name_emp ); len = len < 40 ? len : 39; strncpy( name, name_emp, len ); name[len] = ‘\0’;
}
Порядок создания Об-в
Создание
Объект Ob_Emp 3
1
Объeкт bDate
2
Объeкт hDate
26
Полиморфизм, Виртуальные Функции (ВиртФун)
Пол-м – это одна из фундам-х концепций
ООП-я: различные реализации Фун-й доступны с использов-м одного имени,
“Один интерфейс, много методов”.
ВС++ Пол-м реализован:
во время компиляции (перегрузка Фун),
во время вып-я П.
Полиморфизм, ВиртФун
class Base { . . .
virtual void fun();
class Der1 { . . .
void fun();
class Der2 { . . .
void fun();
“Один интерфейс, много методов” 3
Указатели на производные типы
Указатели на базовый тип и на производный тип зависимы. Пусть имеем базовый тип Вase и производный Der. Ук, объявленный на Вase, может быть также Ук на
Der. Ук, объявленный на Der, не может быть Ук на Вase !!!
27
|
|
Указатели на производные типы |
||
|
|
|
Base b, *pb; |
|
сlass Base |
||||
Der d, *pd; |
||||
{ ~ ~ ~ ~ ~ |
||||
pb = &b; |
||||
~ ~ ~ ~ ~ |
||||
. . . . . |
||||
} |
|
|
||
|
|
pb = &d; |
||
сlass Der: public Base |
||||
{ + + + + |
~ ~ ~ ~ ~ |
pb -> funB(); |
||
((Der*)pb) -> funD(); |
||||
+ + + + ~ ~ ~ ~ ~ |
||||
pd = &b; |
||||
} |
|
|
||
|
|
|
||
|
|
|
1 |
|
Пример |
|
|
||
сlass B |
{ public: |
|
||
|
|
void show() { cout << ” B \n”; } |
||
|
|
}; |
|
|
сlass D : public B |
|
|||
|
{ public: |
|
||
|
}; |
void show() { cout << ” D \n”; } |
||
|
|
|
||
сlass DD : public D |
|
|||
|
{ public: |
|
||
|
}; |
void show() { cout << ” DD \n”; } |
||
|
|
|
||
void main() |
|
|||
{ B |
b, |
*pb; |
|
|
D |
d, |
*pd; |
|
|
DD dd, |
*pdd; |
|
||
pb=&b; b.show(); pb->show(); // B B |
||||
pb=&d; pb->show(); |
// B |
|||
((D*)pb)->show(); |
// D |
|||
pb=ⅆ pb->show(); |
// B |
|||
((DD*)pb)->show(); |
// DD |
|||
pd=ⅆ pd->show(); |
// D |
28
Пример с ВиртФун
сlass B { public:
virtual void show() { cout << ” B \n”; }
};
сlass D : public B { public:
void show() {
};
сlass DD : public D { public:
void show() {
};
void main() |
|
||
{ B |
b, |
*pb; |
|
D |
d, |
*pd; |
virtual * |
DD dd, |
*pdd; |
|
pb=&b; b.show(); pb->show(); |
// B B |
B B |
pb=&d; pb->show(); |
// B |
D * |
((D*)pb)->show(); |
// D |
D |
pb=ⅆ pb->show(); |
// B |
DD * |
pd=ⅆ pd->show(); |
// D |
DD * |
pd -> B :: show(); |
// B |
B |
|
|
|
Выводы:
-Пол-м во время вып-я П поддерж-ся:
наличием производных Классов,
использ-ем ВиртФун;
-Прототипы ВиртФун д.б. одинаковы;
-В цепочке производных Классов ВиртФун может не быть, вызыв-ся ближайшая сверху ВиртФун;
-ВиртФун не м.б. дружеств-й для Класса, в котором Она определена
членом Класса, но ВиртФун м.б. “другом” другого Класса.
29
Чистые ВиртФун и абстрактные Классы
На практике часто ВиртФун в базовом Классе определяют лишь интерфейс.
Такие Фун, не имеющие описания, назыв-ся чистыми ВиртФун. Произв-й Класс должен определить реализацию ВиртФун .
Форма объявления чистой ВиртФун: virtual тип Имя_фун (<список аргум-в>) = 0;
Класс, имеющий хотя бы одну чистую ВиртФун, называется абстрактным. Его
назначение в возможности унаследовать интерфейс в произв-х Классах.
АбстрКласс не может иметь Об-в, но можно объявить Ук на АбстрКласс и использовать Его для Об произв-х Классов – механизм ВиртФун.
Шаблоны Функций и Классов
Шаблон (структура) - трафарет, в кот. мы вкладываем определённые свойства, т.е.
конкретные типы и параметры некоторого
Об-Шаблона. Шаблон – одно из
последних расширений стандарта С++.
Пример: Шаблон - Эллипс
В отличие от перегруженных Функций если для набора типов Данных должны
выполняться идентичные операции, то более компактным решением является
Шаблон.
Идея и механизм Шаблонов – автор Бьерн Страуструп, октябрь 1988 г, «Параметризованные типы Данных».
При компиляции П создаются объектные коды Фун, обрабат-х каждый тип Д.
В языке С эту задачу выполняли макросы, но Комп-р не проверяет в макросах
соответствие типов: побочные эффекты.
Пример:
#define ab(a,b) ((a) + (b))
30