В програмирането, предефинирането на оператор () е специфичен случай на полиморфизъм, при който различните оператори имат различна имплементация зависеща от аргументите ѝ. Предефинирането на оператор се определя от програмния език, програмиста или от двете.
Мотивация При предефинирането на оператори се използва синтаксис, който прави програмния език по-лесен за четене и разбиране или това е така наречената синтактична захар. Операторните декларации са разширение на вече съществуващите в езика оператори върху новосъздадени класове, което позволява на програмиста да използва синтаксис близък до този, който вече е вграден в програмния език.
Често срещано е изчисленията, които се правят в програмата да имат сходен синтаксис до този, който се прави на лист. Например, нека A, B, C са променливи от тип Matrix (матрица): A + B * C
Но в език, който не поддържа предефиниране на оператори това ще има вида: add(A, multiply(B, C))
Примери В този пример, операторът са събиране е предефиниран за да позволи събиране на дефинирани от потребителя типове „Time“ (C++): Time operator+(const Time& lhs, const Time& rhs) { Time temp = lhs; temp.seconds += rhs.seconds; temp.minutes += temp.seconds / 60; temp.seconds %= 60; temp.minutes += rhs.minutes; temp.hours += temp.minutes / 60; temp.minutes %= 60; temp.hours += rhs.hours; return temp; } Операторът за събиране е бинарен, което означава, че използва два операнда. Операцията може да бъде дефинирана и като метод в клас, като единия аргумернт lhs се замести с this , но това означава, че и левият операнд трябва да бъде от тип Time: Time Time::operator+(const Time& rhs) const /* const means that 'this' is not to be modified */ { Time temp = *this; /* Copy 'this' which is not to be modified */ temp.seconds += rhs.seconds; temp.minutes += temp.seconds / 60; temp.seconds %= 60; temp.minutes += rhs.minutes; temp.hours += temp.minutes / 60; temp.minutes %= 60; temp.hours += rhs.hours; return temp; } Унарните оператори, дефинирани в метод на клас могат да не приемат видими аргументи (работят само с this): bool Time::operator!() const { return ((hours == 0) && (minutes == 0) && (seconds == 0)); } Операторът за сравнение „по-малко“ (<) често се предефинира за сортиране на структура или клас: class pair { public: int x,y; bool operator < (const pair& p) const
if(x==p.x) return y<p.y; return x<p.x;
В последния пример, предефинирането на оператора за сравнение „по-малко“ (<) е в конкретен клас, което означава, че могат да се прилагат сортиращи функции с обекти от този клас.
Критика Предефинирането на оператори често бива критикуваноIssues in Overloading, тъй като позволява на програмиста да дава различен смисъл на операторите в зависимост от случаите. Например в C++ оператора <<: а << 1
Ако приемем, че a е реално число, то << ще измести битовете му наляво веднъж, но ако a е поток, то << ще изпише "1" на потока. Това може да доведе до объркване и се счита за добра практика, предефинирането на оператори да се използва внимателно.
Друг проблем, който възниква е, че някои правила от математика са грешно използвани или приети на сляпо. Пример може да се даде с разместително свойство на събирането – нека a и b са променливи. Ако те са числа, то при тях важи, че a + b == b + a, но ако а = "Some" и b = "String" (a + b == „SomeString“ и b + a == „StringSome“), то a + b != b + a. На практика, + не е асоциативен до при числата с плаващата запетая, поради грешки при закръглянето. Подобен пример може да се даде и с умножението, което също има разместително свойство, що се отнася до реални числа, но не и когато става въпрос за умножение на матрици.
Класификация Оператори Непредефинируеми Предефинируеми Ново дефинирани ML Pico Prolog
ALGOL 68 Clojure Eiffel Fortran F# Haskell Io Perl 6 R Scala Seed7 Smalltalk Swift Ограничени BASIC C Go Java JavaScript Modula-2 Objective-C Pascal Ada C# C++ Ceylon D Dart Delphi FreeBASIC Groovy Lua MATHLAB Object Pascal PHP Perl Python Ruby Rust
Вижте също Полиморфизъм Оператор (програмиране)
Източници
Категория:Програмиране