Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции_Классы

.pdf
Скачиваний:
10
Добавлен:
02.06.2015
Размер:
616.21 Кб
Скачать

Реализация Фун перегрузки Оп =

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=&dd; pb->show();

// B

((DD*)pb)->show();

// DD

pd=&dd; pd->show();

// D

28

cout << ” D \n”; }
cout << ” DD \n”; }

Пример с ВиртФун

с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=&dd; pb->show();

// B

DD *

pd=&dd; pd->show();

// D

DD *

pd -> B :: show();

// B

B

 

 

 

Выводы:

-Пол-м во время вып-я П поддерж-ся:

наличием производных Классов,

использ-ем ВиртФун;

-Прототипы ВиртФун д.б. одинаковы;

-В цепочке производных Классов ВиртФун может не быть, вызыв-ся ближайшая сверху ВиртФун;

-ВиртФун не м.б. дружеств-й для Класса, в котором Она определена

членом Класса, но ВиртФун м.б. “другом” другого Класса.

29

Чистые ВиртФун и абстрактные Классы

На практике часто ВиртФун в базовом Классе определяют лишь интерфейс.

Такие Фун, не имеющие описания, назыв-ся чистыми ВиртФун. Произв-й Класс должен определить реализацию ВиртФун .

Форма объявления чистой ВиртФун: virtual тип Имя_фун (<список аргум-в>) = 0;

Класс, имеющий хотя бы одну чистую ВиртФун, называется абстрактным. Его

назначение в возможности унаследовать интерфейс в произв-х Классах.

АбстрКласс не может иметь Об-в, но можно объявить Ук на АбстрКласс и использовать Его для Об произв-х Классов – механизм ВиртФун.

Шаблоны Функций и Классов

Шаблон (структура) - трафарет, в кот. мы вкладываем определённые свойства, т.е.

конкретные типы и параметры некоторого

Об-Шаблона. Шаблон – одно из

последних расширений стандарта С++.

Пример: Шаблон - Эллипс

В отличие от перегруженных Функций если для набора типов Данных должны

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

Шаблон.

Идея и механизм Шаблонов – автор Бьерн Страуструп, октябрь 1988 г, «Параметризованные типы Данных».

При компиляции П создаются объектные коды Фун, обрабат-х каждый тип Д.

В языке С эту задачу выполняли макросы, но Комп-р не проверяет в макросах

соответствие типов: побочные эффекты.

Пример:

#define ab(a,b) ((a) + (b))

30