Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Перевантаження Операторів | Огляд Поліморфізму
C++ ООП
course content

Зміст курсу

C++ ООП

C++ ООП

1. Основи ООП у C++
2. Конструктори та Деструктори
3. Огляд Інкапсуляції
4. Огляд Наслідування
5. Огляд Поліморфізму

book
Перевантаження Операторів

Перевантаження операторів — це потужна можливість у мовах об'єктно-орієнтованого програмування, яка дозволяє перевизначати поведінку операторів для користувацьких classes. Завдяки перевантаженню операторів можна створювати власні реалізації операцій для об'єктів вашого class, що забезпечує більш інтуїтивний та виразний код.

Синтаксис перевантаження операторів

Перевантаження досягається шляхом визначення спеціальних функцій-членів або дружніх функцій, які реалізують необхідну поведінку для оператора. Синтаксис перевантаження операторів залежить від оператора, який ви хочете перевантажити. Загальний вигляд виглядає так:

overloading.h

overloading.h

copy
1
return_type operator operator_symbol(parameters);

Синтаксис, а точніше, кількість параметрів і тип, що повертається, також залежать від того, чи перевантажуєте ви оператори як функції-члени або як дружні функції.

Member.h

Member.h

Friend.h

Friend.h

copy
123456
class Example { public: Example operator+ (const Example& other) { // Define behavior for operator+ } };

Таблиця операторів, які можна перевантажити

Нижче наведено таблицю всіх операторів, які можна перевантажити. Однак важливо зазначити, що хоча перевантаження цих операторів можливе, зовсім не обов'язково перевантажувати всі з них для ваших classes.

Перевантаження операторів вставки у потік

Щоб перевантажити оператори << та >> для class, зазвичай визначають функцію-друга або метод-член, який приймає потік виводу (std::ostream&) або потік вводу (std::istream&) як лівий операнд і об'єкт вашого class як правий операнд. Ця функція форматує дані об'єкта та передає їх у потік або з потоку.

Point.h

Point.h

copy
123456789101112131415
class Point { public: friend std::ostream& operator<<(std::ostream& out, const Point& point); friend std::istream& operator>>(std::istream& in, Point& point); private: int x, y; }; std::ostream& operator<<(std::ostream& out, const Point& point) { return out << "x: " << point.x << ", y: " << point.y << std::endl; } std::istream& operator>>(std::istream& in, Point& point) { return in >> point.x >> point.y; }

Перевантаження операторів вставки у потік, таких як <<, дозволяє визначити власну поведінку виводу для об'єктів ваших classes при передачі їх у потік виводу, наприклад, у std::cout. Ця можливість особливо корисна для підвищення читабельності та зручності використання вашого коду при роботі з власними типами даних.

Note
Примітка

Перевантаження оператора << для потоку виводу є більш поширеним, ніж перевантаження оператора >> для потоку вводу, оскільки операції вводу з >> можуть бути більш схильними до помилок.

Перевантаження арифметичних операторів

Можна перевантажувати й інші арифметичні оператори (-, *, /, %) аналогічним чином для виконання користувацьких операцій з вашими власними типами.

main.cpp

main.cpp

copy
12345678910111213141516171819202122
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} Point operator+(const Point& other) { return Point(x + other.x, y + other.y); } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p = Point(2, 4) + Point(2, 6); std::cout << p.getX() << ' ' << p.getY() << std::endl; }

Оператор перевантажується як метод-член Point class. Він приймає інший об'єкт типу Point як параметр і повертає новий об'єкт типу Point, який представляє суму двох точок. Оператор + можна замінити на -, *, / або % з відповідними змінами в логіці реалізації.

Інкремент і декремент

Як префіксний, так і постфіксний інкремент і декремент (++ та --) можна перевантажити для користувацьких classes. Почнемо з префіксної версії:

main.cpp

main.cpp

copy
123456789101112131415161718192021222324
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} // Prefix increment operator (++point) Point& operator++() { ++x; ++y; return *this; } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p(2, 2); ++p; std::cout << p.getX() << ' ' << p.getY() << std::endl; }
Note
Примітка

Оператор декременту перевантажується аналогічно оператору інкременту, використовуючи оператор -- та операцію віднімання.

Як бачите, перевантаження префіксних операторів інкременту та декременту є простим. Однак із постфіксними версіями виникають складнощі. Зверніть увагу, що існує різниця в порядку виконання між префіксними та постфіксними операціями.

Під час перевантаження постфіксних операторів інкременту та декременту також необхідно реалізувати особливість порядку виконання. Це виглядатиме приблизно так:

main.cpp

main.cpp

copy
1234567891011121314151617181920212223242526
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} // Postfix increment operator (point++) Point operator++(int) { Point temp = *this; // Creating a temp variable ++(this->x); // Incrementing original Point's x ++(this->y); // Incrementing original Point's y return temp; // Returning created temp variable } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p(2, 2); p++; std::cout << p.getX() << ' ' << p.getY() << std::endl; }
Note
Примітка

Цілий параметр передається без імені лише для того, щоб повідомити компілятору, що перевантажується оператор постфіксного інкременту. Це необхідно, оскільки оголошення для префіксного та постфіксного операторів інакше ідентичні.

У реалізації оператора постфіксного інкременту початкове значення об'єкта зберігається у тимчасовій змінній (temp). Поточний об'єкт потім інкрементується, але оператор повертає значення, збережене у temp. Це означає, що змінна інкрементується, але зміна набуває чинності лише у наступному виразі, оскільки оператор повертає початкове значення.

question mark

Що означає перевантаження операторів?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 5. Розділ 4

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

course content

Зміст курсу

C++ ООП

C++ ООП

1. Основи ООП у C++
2. Конструктори та Деструктори
3. Огляд Інкапсуляції
4. Огляд Наслідування
5. Огляд Поліморфізму

book
Перевантаження Операторів

Перевантаження операторів — це потужна можливість у мовах об'єктно-орієнтованого програмування, яка дозволяє перевизначати поведінку операторів для користувацьких classes. Завдяки перевантаженню операторів можна створювати власні реалізації операцій для об'єктів вашого class, що забезпечує більш інтуїтивний та виразний код.

Синтаксис перевантаження операторів

Перевантаження досягається шляхом визначення спеціальних функцій-членів або дружніх функцій, які реалізують необхідну поведінку для оператора. Синтаксис перевантаження операторів залежить від оператора, який ви хочете перевантажити. Загальний вигляд виглядає так:

overloading.h

overloading.h

copy
1
return_type operator operator_symbol(parameters);

Синтаксис, а точніше, кількість параметрів і тип, що повертається, також залежать від того, чи перевантажуєте ви оператори як функції-члени або як дружні функції.

Member.h

Member.h

Friend.h

Friend.h

copy
123456
class Example { public: Example operator+ (const Example& other) { // Define behavior for operator+ } };

Таблиця операторів, які можна перевантажити

Нижче наведено таблицю всіх операторів, які можна перевантажити. Однак важливо зазначити, що хоча перевантаження цих операторів можливе, зовсім не обов'язково перевантажувати всі з них для ваших classes.

Перевантаження операторів вставки у потік

Щоб перевантажити оператори << та >> для class, зазвичай визначають функцію-друга або метод-член, який приймає потік виводу (std::ostream&) або потік вводу (std::istream&) як лівий операнд і об'єкт вашого class як правий операнд. Ця функція форматує дані об'єкта та передає їх у потік або з потоку.

Point.h

Point.h

copy
123456789101112131415
class Point { public: friend std::ostream& operator<<(std::ostream& out, const Point& point); friend std::istream& operator>>(std::istream& in, Point& point); private: int x, y; }; std::ostream& operator<<(std::ostream& out, const Point& point) { return out << "x: " << point.x << ", y: " << point.y << std::endl; } std::istream& operator>>(std::istream& in, Point& point) { return in >> point.x >> point.y; }

Перевантаження операторів вставки у потік, таких як <<, дозволяє визначити власну поведінку виводу для об'єктів ваших classes при передачі їх у потік виводу, наприклад, у std::cout. Ця можливість особливо корисна для підвищення читабельності та зручності використання вашого коду при роботі з власними типами даних.

Note
Примітка

Перевантаження оператора << для потоку виводу є більш поширеним, ніж перевантаження оператора >> для потоку вводу, оскільки операції вводу з >> можуть бути більш схильними до помилок.

Перевантаження арифметичних операторів

Можна перевантажувати й інші арифметичні оператори (-, *, /, %) аналогічним чином для виконання користувацьких операцій з вашими власними типами.

main.cpp

main.cpp

copy
12345678910111213141516171819202122
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} Point operator+(const Point& other) { return Point(x + other.x, y + other.y); } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p = Point(2, 4) + Point(2, 6); std::cout << p.getX() << ' ' << p.getY() << std::endl; }

Оператор перевантажується як метод-член Point class. Він приймає інший об'єкт типу Point як параметр і повертає новий об'єкт типу Point, який представляє суму двох точок. Оператор + можна замінити на -, *, / або % з відповідними змінами в логіці реалізації.

Інкремент і декремент

Як префіксний, так і постфіксний інкремент і декремент (++ та --) можна перевантажити для користувацьких classes. Почнемо з префіксної версії:

main.cpp

main.cpp

copy
123456789101112131415161718192021222324
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} // Prefix increment operator (++point) Point& operator++() { ++x; ++y; return *this; } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p(2, 2); ++p; std::cout << p.getX() << ' ' << p.getY() << std::endl; }
Note
Примітка

Оператор декременту перевантажується аналогічно оператору інкременту, використовуючи оператор -- та операцію віднімання.

Як бачите, перевантаження префіксних операторів інкременту та декременту є простим. Однак із постфіксними версіями виникають складнощі. Зверніть увагу, що існує різниця в порядку виконання між префіксними та постфіксними операціями.

Під час перевантаження постфіксних операторів інкременту та декременту також необхідно реалізувати особливість порядку виконання. Це виглядатиме приблизно так:

main.cpp

main.cpp

copy
1234567891011121314151617181920212223242526
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} // Postfix increment operator (point++) Point operator++(int) { Point temp = *this; // Creating a temp variable ++(this->x); // Incrementing original Point's x ++(this->y); // Incrementing original Point's y return temp; // Returning created temp variable } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p(2, 2); p++; std::cout << p.getX() << ' ' << p.getY() << std::endl; }
Note
Примітка

Цілий параметр передається без імені лише для того, щоб повідомити компілятору, що перевантажується оператор постфіксного інкременту. Це необхідно, оскільки оголошення для префіксного та постфіксного операторів інакше ідентичні.

У реалізації оператора постфіксного інкременту початкове значення об'єкта зберігається у тимчасовій змінній (temp). Поточний об'єкт потім інкрементується, але оператор повертає значення, збережене у temp. Це означає, що змінна інкрементується, але зміна набуває чинності лише у наступному виразі, оскільки оператор повертає початкове значення.

question mark

Що означає перевантаження операторів?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 5. Розділ 4
some-alt