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

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

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

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