Разделы презентаций


This.Перегрузка

Содержание

thisГоворят, что в функцию в этом случаепередается неявный указатель на этотобъект. Его можно задать и явно с помощью ключевого слова this. Например,void Print() { cout line; }Однако в данном случае

Слайды и текст этой презентации

Слайд 1п4. Неявный указатель this
Каждый объект класса имеет свою копию член-
данных,

но один экземпляр каждой член-
функции для всех объектов.
Возникает вопрос,

как же член-функция
“понимает”, с член-данными какого объекта она
работает?
Ответ очевиден - с теми, которые принадлежат
объекту, вызвавшему эту функцию.
Например,
s2.Print(); // с член-данными объекта s2
п4. Неявный указатель thisКаждый объект класса имеет свою копию член-данных, но один экземпляр каждой член-функции для всех

Слайд 2this
Говорят, что в функцию в этом случае
передается неявный указатель на

этот
объект. Его можно задать и явно с
помощью ключевого слова

this.
Например,
void Print() { cout << this->line; }

Однако в данном случае - это излишне.
thisГоворят, что в функцию в этом случаепередается неявный указатель на этотобъект. Его можно задать и явно с

Слайд 3Но бывают ситуации (кстати,
довольно частые при использовании
ООП), когда приходится задавать
этот

указатель явно.

Но бывают ситуации (кстати,довольно частые при использованииООП), когда приходится задаватьэтот указатель явно.

Слайд 4Пример
В классе String определим функцию,
которая будет к первой строке
приписывать вторую

и результатом
возвращать первую
(конкатенация строк),
объявив ее в классе
String Plus(String &);

ПримерВ классе String определим функцию,которая будет к первой строкеприписывать вторую и результатомвозвращать первую(конкатенация строк), объявив ее в

Слайд 5и определив ее за классом:
String String :: Plus (String &s2)
{char

*t = new char[ len+1];
strcpy(t, line); delete []line;
len

= len+s2.len; // новая длина
line = new char[ len+1];
strcpy(line, t);
strcat(line, s2.line);
delete [] t;

Вернуть надо 2 поля line и len. Но так
return line, len;
нельзя!


return *this; } //возвращаем «этот» объект

и определив ее за классом:String String :: Plus (String &s2){char *t = new char[ len+1]; strcpy(t, line);

Слайд 6Пример использования функции Plus:

String s1(“Объект “),s2(“класса String.”);
String *s3 = new

String(s1.Plus(s2));
// работает функция Plus,
// а затем конструктор копирования
//

при создании динамического объекта s3
s3->Print();
// вывод *s3 = ”Объект класса String.”;

Пример использования функции Plus:String s1(“Объект “),s2(“класса String.”);String *s3 = new String(s1.Plus(s2)); // работает функция Plus, // а

Слайд 7п5. Перегрузка операций
New. Перегрузка функций.
Это одно из проявлений полиморфизма в

С++.
Перегрузка функций - это использование
одинаковых имен для однотипных функций.
Рассмотрим на

примере.
Пусть требуется написать 3 функции вывода:
массива a из m целых чисел;
длинного целого числа;
строки символов.
п5. Перегрузка операцийNew. Перегрузка функций.Это одно из проявлений полиморфизма в С++.Перегрузка функций - это использованиеодинаковых имен для

Слайд 8Начинаем работу с «придумывания
имен», например:
void Printm (int *a,

int m) для массива,
void Printl (long n) для

длинного целого,
void Prints (char *s) для строки.
В С++ все эти 3 функции могут быть заданы одним именем

void Print (int *a, int m)
void Print (long n)
void Print (char *s)

Начинаем работу с «придумыванияимен», например:void   Printm (int *a, int m) для массива,void   Printl

Слайд 9Поскольку список формальных
аргументов у каждой функции разный,
т.е. отличается количеством и/или

типом
(говорят - сигнатурой), то при вызове
функций компилятор по списку
фактических

аргументов разберется,
какой экземпляр функции требуется
вызвать.
Print(“Hello!”); // функция Print(char *)
Print(a, 20); // функция Print(int *, int)
Print( 50000l ); // функция Print(long)
Поскольку список формальныхаргументов у каждой функции разный,т.е. отличается количеством и/или типом(говорят - сигнатурой), то при вызове функций

Слайд 10Конструкторы - полиморфизм
Заметим, что определение
нескольких конструкторов в
классе - это перегрузка

функций,
т.е. проявление полиморфизма
для член-функций класса.

Конструкторы - полиморфизмЗаметим, что определениенескольких конструкторов вклассе - это перегрузка функций,т.е. проявление полиморфизмадля член-функций класса.

Слайд 11Возможна двусмысленность!
int sum2(int a, int b)
{ return a+b; }
float sum2(float

a, float b)
{ return a+b; }
void main()
{ int a =

4, b = 5, c; float x = 3.5, y = 2, z;
c = sum2(a, b); cout << “c = ” << c;
// z = sum2(3.5, -1.2);
// Error: Ambiguity between 'sum2(int,int)’ and
// 'sum2(float,float)‘
z = sum2(x, y); // true
cout << “z = ” << z;
}

Причина двусмысленности:
в стандарте языка имеется
преобразование по умолчанию float -> int

Компилятор сомневается,
не применить ли его здесь?!

Решает, что это не в его
компетенции и формирует
ошибку!

двусмысленность

Возможна двусмысленность!int sum2(int a, int b){ return a+b; }float sum2(float a, float b){ return a+b; }void main(){

Слайд 12В таких ситуациях достаточно одной функции
float sum2(float a, float b)
{

return a+b; }

void main()
{ int a = 4, b =

5,c; float x = 3.5, y = 2, z;
c = sum2(a, b);//действует преобразование int ->float
cout << “c = ” << c;
z = sum2(3.5, -1.2);
cout << “z = ” << z;
z = sum2(x, y);
cout << “z = ” << z;
}

Перегрузка функций закончилась

В таких ситуациях достаточно одной функцииfloat sum2(float a, float b){ return a+b; }void main(){ int a =

Слайд 13Перегрузка операций
В С++ можно выполнить перегрузку
операций для объектов класса, то

есть с
помощью знаков операций +, -, *, и т.д.
можно определить

похожие действия для
абстрактных типов данных
Перегрузка операцийВ С++ можно выполнить перегрузкуопераций для объектов класса, то есть спомощью знаков операций +, -, *,

Слайд 14Двуместная операция
тип_возвращаем_знач. operator @ (операнд_2)
{тело_операции},
где @ - знак двуместной

операции.

Первым операндом является объект, в классе
которого эта операция определяется,

т.е. * this,
второй операнд – произвольный (операнд_2).
Используется перегруженный знак так же, как
для стандартных типов данных
операнд1 @ операнд2
Двуместная операциятип_возвращаем_знач. operator @ (операнд_2){тело_операции}, где @ - знак двуместной операции.Первым операндом является объект, в классе которого

Слайд 15Пример 1
В классе String вместо функции Plus можно
определить операцию ‘+=’

String&

String :: operator +=( String &s2 )
{ char *t =

new char[ len+1 ];
strcpy(t, line); // сохраним временно первый операнд!
delete [] line; len = len + s2.len; // новая длина
line = new char[ len+1 ];
strcpy( line, t); strcat( line, s2.line);
delete [] t;
return *this; }

operator +=
вместо имени ч/функции Plus

Пример 1В классе String вместо функции Plus можноопределить операцию ‘+=’String& String :: operator +=( String &s2 ){

Слайд 16Пример использования
В примере из п.4 вместо оператора
String *s3 = new

String(s1.Plus(s2));
можно записать
String *s3= new String(s1+=s2);

String s(“Студент “), r(“Петров “);
s +=

r; // s = “Студент Петров”
Пример использованияВ примере из п.4 вместо оператораString *s3 = new String(s1.Plus(s2));можно записатьString *s3= new String(s1+=s2);String s(“Студент “),

Слайд 17Пример 2
В классе String определим функцию сравнения
двух строк

int String ::

EqStr(String s)
{ if(strcmp(line, s.line)) return 0; //строки не

равны
return 1; // строки равны
}

String s1(“Иванов”), s2(“Петров”);
if ( s1.EqStr(s2)) puts(”Строки равны”);
else puts(”Строки не равны”);

Ответ?

&

Пример 2В классе String определим функцию сравнениядвух строкint String :: EqStr(String   s){ if(strcmp(line, s.line)) return

Слайд 18Перегрузка сравнения ==

int String :: operator == (String

&s)
{if (strcmp(line, s.line)) return 0;
return 1;
}

If

(s1 == s2) puts(”\n Строки равны”);
else {s1. Print(); printf(” - это не “); s2.Print();}

operator ==
вместо имени ч/функции EqStr

Ответ?

Иванов – это не Петров

String s1(“Иванов”), s2(“Петров”);

Перегрузка сравнения ==int  String ::  operator == (String &s){if (strcmp(line, s.line))  return 0; return

Слайд 19Не забыть
При описании класса эти перегруженные
операции надо объявить
class String {

...

public:
...
String& operator += ( String &);
int operator == (String &);
...
};

Не забытьПри описании класса эти перегруженныеоперации надо объявитьclass String { ...

Слайд 20Одноместная операция
тип_возвращаемого_знач. operator @ ( )
{тело_операции}
где @ - знак

одноместной операции.

Обращение
@ операнд
пусто
У одноместной операции единственный операнд и это


*this!
Одноместная операциятип_возвращаемого_знач.  operator @ ( ){тело_операции}где @ - знак одноместной операции.Обращение @ операндпустоУ одноместной операции единственный

Слайд 21Пример 3
Определим операцию реверса строки, т.е.
перестановки символов в обратном порядке.

String

String :: operator ~ ( )
{int i; char t;

for(i = 0; I < len/2; i++)
{t = line[i], line[i] = line[ len – i – 1],
line[len – i – 1] = t;}
return *this;
}
Пример 3Определим операцию реверса строки, т.е.перестановки символов в обратном порядке.String  String :: operator ~ ( ){int

Слайд 22Пример использования
String r(«телефон»);
~r;
r. Print(); // вывод «нофелет»

Пример использованияString r(«телефон»);~r;r. Print(); // вывод «нофелет»

Слайд 23Задача
Задано слово. Является ли слово
«перевертышем»?
void main()
{ String s1(“казак”);
String

s2 = s1;

s1.Print();
if (s1 == ~s2) puts(”

– перевертыш”);
else puts(” - не перевертыш”);
}

Ответ?

казак - перевертыш

Напомню:
приоритет одноместных
операций выше!

// Работает конструктор
// копирования, чтобы не
// изменить s1 операцией ~

ЗадачаЗадано слово. Является ли слово«перевертышем»? void main(){ String s1(“казак”); String s2 = s1;  s1.Print(); if (s1

Слайд 24Правила перегрузки:
При перегрузке операции, как член-
функции класса, двуместная операция
имеет один

аргумент, одноместная – ни
одного;

2. Знак одноместной операции может
быть перегружен только

как
одноместный, а двуместной - только как
двуместный;
Правила перегрузки:При перегрузке операции, как член-функции класса, двуместная операцияимеет один аргумент, одноместная – ниодного;2. Знак одноместной операции

Слайд 25Правила перегрузки (продолжение):
3. Наряду с обычным использованием
перегруженного знака
obj1 @ obj2

для двуместной операции
и
@ obj

для одноместной
он может использоваться как член-функция
класса
obj1.operator @(obj2)
и
obj.operator @()
Правила перегрузки (продолжение):3. Наряду с обычным использованиемперегруженного знакаobj1 @ obj2   для двуместной операциии@ obj

Слайд 26Правила перегрузки (окончание):
4. Нельзя перегружать операции для
стандартных типов данных.
Например, + для

массивов,
определенных, как int * a или int a[20]
.
5. Нельзя перегружать

операции
:: . ?: sizeof
Правила перегрузки (окончание):4. Нельзя перегружать операции длястандартных типов данных.Например, + для массивов,определенных, как int * a или

Слайд 27п6. Примеры перегрузки некоторых операций
1. Перегрузка [ ]
Пусть определен объект
String

s(«Еденица»);

s[2] = ’и’;
// ошибка: операция [ ] в классе
//

String не определена
п6. Примеры перегрузки некоторых операций1. Перегрузка [ ]Пусть определен объектString s(«Еденица»);s[2] = ’и’; // ошибка: операция [

Слайд 28Объяснимся
Действительно, объект может иметь
несколько полей данных типа «массив»
и компилятору неизвестно,

к какому из
массивов мы хотели бы применить
операцию [ ].

ОбъяснимсяДействительно, объект может иметьнесколько полей данных типа «массив»и компилятору неизвестно, к какому измассивов мы хотели бы применитьоперацию

Слайд 29Вместо функции Index (см п. 2), определим операцию [ ]

char

& String :: operator [ ] ( int i)
{ if

(i<0 || i>=len) {puts(“Индекс за пределами строки»);
exit(0);}
return line[i];
}

s[2] = ’и’; // ”Единица”

cout << s[0]; // вывод буквы ‘Е’


Не забудем объявить её в классе
char & operator [ ] (int );

Трактуется компилятором
как двуместная операция

это возможно благодаря char &

Вместо функции Index (см п. 2), определим операцию [ ]char & String :: operator [ ] (

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика