Przeciążanie operatorów to możliwość definiowania zachowania standardowych operatorów (np. +, -, *, ==) dla własnych klas. Pomaga to pisać ekspresyjny, czytelny kod podczas pracy z typami użytkownika (np. wektor, macierz).
Mechanizm przeciążania operatorów pojawił się w C++ w celu wsparcia intuicyjnej składni podczas pracy z obiektami (np. dodawanie liczb zespolonych, praca z iteratorem) tak, jak to się robi z typami podstawowymi.
Bez przeciążania operatorów wiele operacji wyglądałoby jak zwykłe funkcje (add(a, b)), co komplikuje czytanie kodu i zmniejsza jego ekspresyjność. Jednak nadmierne lub niewłaściwe użycie prowadzi do zamieszania i błędów.
W C++ można przeciążać większość operatorów, deklarując odpowiednie funkcje członkowskie lub przyjacielskie, aby określić logikę dla nowych operacji.
Przykład kodu:
class Vector2D { double x, y; public: Vector2D(double x, double y) : x(x), y(y) {} Vector2D operator+(const Vector2D& rhs) const { return Vector2D(x + rhs.x, y + rhs.y); } };
Kluczowe cechy:
Czy można przeciążyć operator . (kropka) i :: (dwukropek)?
Nie, takie operatory jak . (kropka), ::, sizeof, ?: i niektóre inne nie mogą być przeciążane zgodnie ze standardem języka.
Czy zachowanie przeciążonych operatorów musi całkowicie odpowiadać ich standardowej semantyce?
Nie musi, ale jest zalecane (na przykład, przeciążając ==, należy porównywać równość).
Co się stanie przy niewłaściwym przekazywaniu obiektu przez wartość do przeciążonego operatora?
Można uzyskać niepotrzebne kopiowanie lub dereferencje, co spowolni program lub doprowadzi do błędu. Lepiej przekazywać stałą referencję (const T&).
Przykład kodu:
Vector2D operator+(Vector2D rhs) const; // nieefektywne, obiekt jest kopiowany
W klasie DataFrame przeciążono operator * do iloczynu skalarnego z efektem ubocznym (modyfikacja obiektu).
Zalety:
Wady:
W klasie liczb zespolonych przeciążono +, -, == z typową logiką matematyczną, bez modyfikacji oryginalnych obiektów.
Zalety:
Wady: