4.Перегрузка операторов.pptx
- Количество слайдов: 30
4. Перегрузка операторов
4. 1. Перегрузка операторов тип operator знак_оперции (параметры) Нельзя изменить: – количество операндов оператора – приоритет оператора – правило ассоциативности оператора Нельзя перегружать: : : . . * ? : Первый операнд – имя Тернарный 2
4. 2. Перегрузка операторов: пример class Rational { public: . . . add Rational operator +(const Rational& r) const; . . . }; Бинарный оператор +: первый операнд – через this, второй – параметр r 3
4. 2. Перегрузка операторов: пример (продолжение) Rational: : operator +(const Rational &r) const { Rational tmp; tmp. num = num*r. den + den*r. num; tmp. den = den*r. den; tmp. reduce(); return tmp; } 4
4. 3. Использование перегруженных операторов Rational a(1, 5), b(2, 7), c; c = a + b; эквивалентно c = a. operator +(b); // a. add(b) 5
4. 4. Операторы ++, - • Префиксный ++: Прототип: тип operator ++(); Использование: ++a; или a. operator ++(); • Постфиксный ++: Прототип: тип operator ++(int); Использование: a++; или a. operator ++(0); 6
4. 5. Перегрузка оператора ++: примеры class Rational { public: Rational & operator ++(); Rational operator ++(int); . . . }; 7
4. 5. Перегрузка оператора ++: примеры (продолжение) Rational & Rational: : operator ++() { num += den; return *this; } 8
4. 5. Перегрузка оператора ++: примеры (продолжение) Rational: : operator ++(int) { Rational x(*this); num += den; return x; } 9
4. 6. Друзья класса Вывод в поток: Rational r; std: : cout << r << std: : endl; class Rational { friend std: : ostream & operator <<( std: : ostream &, const Rational &); … }; 10
4. 6. Друзья класса (продолжение) std: : ostream & operator <<(std: : ostream &c, const Rational &r) std: : ostream & Rational: : print( { std: : ostream &c) const c << r. num; { c << num; if(r. den > 1) if(den > 1) c << '/'<< r. den; c << '/'<< den; return c; } } 11
4. 6. Друзья класса (продолжение) class X { friend. . . ; . . . }; class S { friend class X; . . . }; 12
4. 7. Друзья или члены класса Общее: • Имеют доступ к private / protected областям класса • Хотя бы один параметр – экземпляр класса 13
4. 7. Друзья или члены класса (продолжение) Отличия: Член класса Друг класса • Есть неявный параметр this • Первый операнд – адресат метода, остальные – в списке параметров • Первый операнд – экземпляр класса • Нет неявного параметра this • Все операнды в списке параметров • Порядок задания операндов определяется семантикой оператора 14
4. 8. Правила выбора Функции-члены класса Обязательно: • конструкторы, деструкторы, виртуальные функции; • операторы =, (), [ ], ->, преобразования типа Желательно: • все остальные операторы (за некоторым исключением) 15
4. 8. Правила выбора (продолжение) Функции-друзья класса: • бинарные операторы, требующие неявного преобразования операндов (аргументы – константные ссылки или не ссылки) • бинарные операторы, первый операнд которых – не экземпляр класса 16
4. 9. Преобразования типа Новый класс (тип) – T (например, Rational) Rational r; Существующий тип – S (например, int) int n; 1. Преобразование из S в T: r = n; -- конструктор (неявное) 2. Преобразование из T в S: n = r; -- перегруженный оператор 17
4. 10. Инициализирующий конструктор class Rational { public: Rational (int n): num(n), den(1){} Rational operator +(const Rational &r) const; . . . }; Rational r; r = 5; …r+3… но! 3 + r – ошибка! Rational(3) + r – ok! 18
4. 10. Инициализирующий конструктор (продолжение) class Rational { public: explicit Rational(double); … }; 19
4. 10. Инициализирующий конструктор (продолжение) Rational r; double x; r = x; --- ошибка! r = Rational(x); --- ok! … r + x … --- ошибка! … r + Rational(x) … --- ок! … Rational(x) + r … --- ок! 20
4. 11. Оператор преобразования типа class Rational { public: operator double() const { return (double) num / den; }. . . }; 21
4. 11. Оператор преобразования типа (продолжение) Rational r; double x; x = r; или x = (double) r; 22
4. 12. Возможные проблемы class Rational { public: Rational(int); // Rational int (1) Rational operator + (const Rational &) const; friend Rational operator +(int, const Rational &); operator int(); // int Rational (2). . . }; 23
4. 12. Возможные проблемы (продолжение) Rational r; int n; … r + n … --- Rational + int (2) (1) Rational + Rational ? (1) int + Rational ? (2) int + int ? 24
4. 13. Индексирование class S { private: static const int M = 100, N = 80; int n; char words[M][N]; public: . . . int operator[ ] ( const char *) const; const char *operator[ ] (int) const; }; 25
4. 14. Индексирование: реализация int S: : operator [ ] (const char *w) const { for(int j = 0; j < n; ++j) if(strcmp(words[j], w) == 0) return j; return -1; } 26
4. 14. Индексирование: реализация (продолжение) const char * S: : operator [ ] (int w) const { if(w < 0 || w >= n) throw “illegal index”; return words[w]; } 27
4. 15. Индексирование: использование S ob; . . . int k = ob[“hello”]; . . . S arr[10]; const char *j = NULL; j = arr[ i ][ k ]; Элемент массива arr Перегруженный оператор 28
4. 16. Вызов функции class S { private: double a, b, c; // a*x 2 + b*x + c public: . . . double operator()(double) const; . . . }; // класс – функтор 29
4. 17. Вызов функции: реализация и использование double S: : operator () (double x) const { return a*x*x + b*x + c; }. . . S ob; double y = ob(1. 5); 30