Перегрузка операций. Язык С++. (Лекция 9)

Содержание

Слайд 2

Операции со встроенными типами
int i, j, k;
float x, y;
k =

Операции со встроенными типами int i, j, k; float x, y; k
i + j;
if (x > y)
i++;

Слайд 3

Способы перегрузки операторов

2 способа объявления операторной функции:
1) как глобальной функции,
2)

Способы перегрузки операторов 2 способа объявления операторной функции: 1) как глобальной функции, 2) как метода класса.
как метода класса.

Слайд 4

Оператор как глобальная функция
Синтаксис объявления глобальной функции


тип operator# ( список_аргументов

Оператор как глобальная функция Синтаксис объявления глобальной функции тип operator# ( список_аргументов
);

# - символ оператора (+, -, <, ++ и т.д.).

Слайд 5

1) Объявление класса и операторных функций (заголовочный файл модуля complex).
...
class

1) Объявление класса и операторных функций (заголовочный файл модуля complex). ... class
complex
{
public:
float re, im;
};
complex operator+(complex a, complex b);
complex operator-(complex a, complex b);
complex operator*(complex a, complex b);
complex operator/(complex a, complex b);
...

Пример: класс комплексных чисел

Слайд 6

#include
#include "complex.h"
using namespace std;
void main()
{
complex a(0.,

#include #include "complex.h" using namespace std; void main() { complex a(0., 1.),
1.), b(-1., 0.), c, d;
c = a + b; // неявный вызов
d = operator+(b, c); // явный вызов
cout << "c=(" << c.re << "," << c.im << ");";
cout << "d=(" << d.re << "," << d.im << ");";
cin.get();
}

2) Использование перегруженных операторов (файл драйвера).

Слайд 7

#include "complex.h"
complex operator+ (complex c1, complex c2)
{
complex tmp;
tmp.re

#include "complex.h" complex operator+ (complex c1, complex c2) { complex tmp; tmp.re
= c1.re + c2.re;
tmp.im = c1.im + c2.im;
return tmp;
}

3) Реализация перегруженного оператора сложения (файл реализации модуля complex).

Слайд 8

Не допускается определять новые операторы (например, **).
Не допускается перегружать операторы встроенных типов.
Перегруженный

Не допускается определять новые операторы (например, **). Не допускается перегружать операторы встроенных
оператор может быть методом класса или глобальной функцией.
Операторы подчиняются правилам приоритета, группирования и числа операндов.
Если имеется и унарная, и бинарная версия оператора (например, &, *, +, -), то они перегружаются отдельно.
Перегруженные операторы не имеют аргументов по умолчанию.
Все перегруженные операторы, кроме оператора присваивания, наследуются

Правила перегрузки операторов

Слайд 9

Дружественные функции

Если оператор определен как глобальная (внешняя) функция, то доступ к закрытым

Дружественные функции Если оператор определен как глобальная (внешняя) функция, то доступ к
(private) и защищенным (protected) полям и методам для нее запрещен.
Однако это ограничение не касается дружественных (friend) функций, которые имеют доступ ко всем полям класса.
Дружественная функция объявляется внутри класса с ключевым словом friend, однако не является методом класса.

Слайд 10

...
class complex
{
private:
float re, im;
friend complex operator~(const complex

... class complex { private: float re, im; friend complex operator~(const complex
c);
};
...

Пример: класс complex и дружественные функции-операторы
complex operator~ (const complex c)
{
complex tmp;
tmp.re = c.re;
tmp.im =-c.im;
return tmp;
}

доступ к закрытым полям

Слайд 11

Оператор как метод класса

Операторная функция может быть объявлена не только как глобальная

Оператор как метод класса Операторная функция может быть объявлена не только как
и дружественная, но и как метод класса.
В этом случае функция объявляется в открытой (public) части определения класса. Количество аргументов функции при этом на единицу меньше, чем арность соответствующего оператора.
Таким образом, унарные операторы (~, !, *, &, ++,...) объявляются как методы без аргументов, а бинарные операторы (<,>, ==, &, ||, >>, <<, ...) - с одним аргументом.

Слайд 12

Объявим операторные функции сложения (бинарный оператор +) комплексных чисел и операцию комплексного

Объявим операторные функции сложения (бинарный оператор +) комплексных чисел и операцию комплексного
сопряжения (унарный оператор ~) как методы класса complex.
...
class complex
{
float re, im;
public:
complex operator+(const complex a);
complex operator~();
};
...

Пример: класс complex

Слайд 13


complex complex::operator+(const complex c)
{
complex tmp;
tmp.re = re

complex complex::operator+(const complex c) { complex tmp; tmp.re = re + c.re;
+ c.re;
tmp.im = im + c.im;
return tmp;
}
complex complex::operator~()
{
complex tmp;
tmp.re = re;
tmp.im =-im;
return tmp;
}

Реализация операторных методов


tmp.re = this->re + c.re;
tmp.im = this->im + c.im;
tmp.re = this->re;
tmp.im =-this->im;

Слайд 14

Вызов операторных функций:
1) явный (с указанием имени функции)
complex a(1.,0), b(0.,1.), c,

Вызов операторных функций: 1) явный (с указанием имени функции) complex a(1.,0), b(0.,1.),
d;
c = a.operator+(b);
d = c.operator~();
2) неявный (с помощью символа операции)
complex a(1.,0), b(0.,1.), c, d;
c = a + b;
d = ~c;

Слайд 15

При выборе способа перегрузки оператора (глобальная функция или метод класса) необходимо принимать

При выборе способа перегрузки оператора (глобальная функция или метод класса) необходимо принимать
во внимание, что
1) некоторые операторы могут перегружаться только как глобальные функции (пример ниже);
2) некоторые операторы могут перегружаться только как методы класса ( =, (), [], ->);
3) некоторые операторы не могут быть перегружены вообще (., .*, ::, ?:, #, ##).

Выбор способа перегрузки - I.

Слайд 16

Несмотря на то, что выбор способа перегрузки оператора остается за программистом, существуют

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

Выбор способа перегрузки - II.

Слайд 17

1) Оператор присваивания =.
Реализуется компилятором неявно с использованием "поверхностного копирования". Должен быть

1) Оператор присваивания =. Реализуется компилятором неявно с использованием "поверхностного копирования". Должен
переопределен явно в случаях, когда объект класса содержит неразделяемую ссылку (например, динамический указатель).
Для объектов с неразделяемыми ссылками необходима реализация "глубокого копирования". Кроме того, вместе с оператором = требуется также явным образом определить конструктор копирования и деструктор (Правило Трех).

Особенности реализации некоторых операторов

Слайд 18

1) объявление
complex& operator=(const complex& c);
2) определение (реализация)
complex& complex::operator=(const complex& c)
{
re

1) объявление complex& operator=(const complex& c); 2) определение (реализация) complex& complex::operator=(const complex&
= c.re;
im = c.im;
return *this;
}

Слайд 19

2) Операторы потокового ввода/вывода (>>, <<)
При использовании операторов сдвига >> и

2) Операторы потокового ввода/вывода (>>, При использовании операторов сдвига >> и > x, cout
<< левым операндом всегда является потоковый объект (например, cin >> x, cout << y). В этом случае операторная функция может быть объявлена только как глобальная и дружественная.
Имя файла: Перегрузка-операций.-Язык-С++.-(Лекция-9).pptx
Количество просмотров: 64
Количество скачиваний: 1