- •Введение в перегрузку операций
- •Операции, как функции
- •Использование перегруженных операций
- •Ограничения в перегрузке операций
- •Перегрузка операций через дружественные функции
- •Перегрузка операций через дружественные функции
- •Int main () {
- •I have 16 dollars.
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Дружественные функции могут быть определены внутри класса
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Перегрузка операций с операндами разных типов
- •Int m_dollars;
- •Int getDollars () {return m_dollars;}
- •Int main () {
- •Values (int min, int max) {
- •Int getMin () {return m_min;}
- •Int getMax () {return m_max;}
- •Int main () {
- •Int main () {
- •Int main () {
- •Перегрузка операций через обычные функции
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Перегрузка операций ввода и вывода
- •Void print () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int m_numerator;
- •Int m_denominator;
- •Void reduce () {
- •Void print () {
- •Перегрузка операций через методы классов
- •Int m_dollars;
- •Int getDollars () { return m_dollars; }
- •Int main () {
- •Int m_dollars;
- •Int getDollars () {return m_dollars;}
- •Int main (){
- •Не всё может быть перегружено через дружественные функции
- •Не всё может быть перегружено через методы класса
- •Int main (){
- •Какой способ перегрузки и когда следует использовать?
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •If (!isHappy)
- •Int main () {
- •If (!something)
- •Перегрузка операций сравнения
- •Int main () {
- •Int m_dollars;
- •Int main () {
- •Перегрузка операторов инкремента и декремента
- •Int m_number;
- •Int main () {
- •Перегрузка операций инкремента и декремента версии постфикс
- •Int m_number;
- •Int main () {
- •Перегрузка операции индексации []
- •Почему оператор индексации [] использует возврат по ссылке?
- •Использование оператора индексации с константными объектами класса
- •Int& operator[] (const int index);
- •Int main (){
- •IntArray array;
- •Проверка ошибок
- •Int m_array[10];
- •Int& operator [] (const int index);
- •Int& IntArray::operator[] (const int index) {
- •Указатели на объекты и перегруженный оператор []
- •Передаваемый аргумент не обязательно должен быть целым числом
- •Void operator [] (std::string index);
- •Void Something::operator [] (std::string index){
- •Int main () {
- •Перегрузка операции ()
- •Int main () {
- •Void operator() ();
- •Void Matrix::operator()() {
- •Int main() {
- •Перегрузка операций преобразования типов данных
- •Int m_dollars;
- •Int getDollars () { return m_dollars; }
- •Int main () {
Int main () {
Dollars ten (10);
Dollars seven (7);
if (ten > seven)
std::cout << "Ten dollars are greater than seven dollars.\n";
if (ten >= seven)
std::cout << "Ten dollars are greater than or equal to seven dollars.\n";
if (ten < seven)
std::cout << "Seven dollars are greater than ten dollars.\n";
if (ten <= seven)
std::cout << "Seven dollars are greater than or equal to ten dollars.\n";
return 0;
}
Всё просто.
Но, как вы уже могли бы заметить, операции (> и <=) являются логическими противоположностями, поэтому одну из них можно было бы определить через вторую.
Та же ситуация и с (< и >=).
Но, поскольку определения функций перегрузки столь просты, а операции в строке объявления функции так хорошо сочетаются с операциями в строке возврата результата, мы этого не делали.
Тест
Задание №1
Используя класс Dollars, приведенный выше, перепишите операторы < и <=, используя их логические противоположности.
Задание №2
Добавьте перегрузку операторов << и < в класс Car, представленный выше, чтобы следующий фрагмент кода:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main () {
std::vector<Car> v;
v.push_back (Car("Ford", "Mustang"));
v.push_back(Car("Renault", "Logan"));
v.push_back(Car("Ford", "Ranger"));
v.push_back(Car("Renault", "Duster"));
std::sort(v.begin(), v.end()); // требуется перегрузка оператора < //для класса Car
for (auto &car : v)
std::cout << car << '\n'; // требуется перегрузка оператора << //для класса Car
return 0;
}
Выдавал следующий результат:
(Ford, Mustang)
(Ford, Ranger)
(Renault, Duster)
(Renault, Logan)
Перегрузка операторов инкремента и декремента
Перегрузка операций инкремента (++) и декремента (−−) довольно-таки проста, но с одним маленьким нюансом.
Есть две версии операторов инкремента и декремента: версия префиксная (например, ++x, --y) и версия постфиксная (например, x++, y--).
Поскольку операции инкремента и декремента являются унарными и изменяют свои операнды, то перегрузку следует выполнять через методы класса.
Перегрузка операций инкремента и декремента версии префикс аналогична перегрузке любых других унарных операторов:
#include <iostream>
class Number {
private:
Int m_number;
public:
Number (int number=0): m_number (number) { }
Number& operator++ ();
Number& operator-- ();
friend std::ostream& operator<< (std::ostream &out, const Number &n);
};
Number& Number::operator++ () {
// Если значением переменной m_number является 8, то выполняем //сброс значения m_number на 0
if (m_number == 8)
m_number = 0;
// В противном случае, просто увеличиваем m_number на единицу
else
++m_number;
return *this;
}
Number& Number::operator--() {
// Если значением переменной m_number является 0, то присваиваем //m_number значение 8
if (m_number == 0)
m_number = 8;
// В противном случае, просто уменьшаем m_number на единицу
else
--m_number;
return *this;
}
std::ostream& operator<< (std::ostream &out, const Number &n) {
out << n.m_number;
return out;
}
