Очевидними прикладами відповідного перевантаження оператора є будь-які класи, які ведуть себе так, як діють числа. Тож класи BigInt (як пропонує Джалайн ), складні числа або матричні класи (як пропонує Superbest ) усі мають ті ж операції, що звичайні числа так добре відображаються на математичних операторах, тоді як операції з часом (як пропонує Svick ) добре відображають на підмножину цих операцій.
Трохи більш абстрактно, операторів можна використовувати при виконанні операцій, встановлених на зразок , так що це operator+може бути об'єднання , operator-може бути доповненням і т. Д. Це дійсно починає розтягувати парадигму, особливо якщо ви використовуєте оператор додавання або множення для операції, яка не є ' t комутативні , як ви могли їх очікувати.
Сам C # є прекрасним прикладом нечислового перевантаження оператора. Він використовує +=та -=додає та віднімає делегатів , тобто реєструє та скасовує їх. Це добре працює , тому що +=і -=оператори працюють , як можна було б очікувати їх до, і цей результат в набагато більш лаконічному коді.
Для пуристів одна з проблем +оператора рядків полягає в тому, що він не є комутативним. "a"+"b"не те саме, що "b"+"a". Ми розуміємо цей виняток для рядків, оскільки він настільки поширений, але як ми можемо визначити, чи використання operator+інших типів буде комутативним чи ні? Більшість людей вважають, що це так, якщо об'єкт не є стрункоподібним , але ви ніколи не знаєте, що припускатимуть люди.
Як і у випадку з рядками, досить добре відомі також і байки матриць. Очевидно, що Matrix operator* (double, Matrix)це скалярне множення, тоді як, наприклад, Matrix operator* (Matrix, Matrix)було б матричне множення (тобто матриця множення крапкових продуктів).
Аналогічно використання операторів з делегатами настільки далеко від математики, що ви навряд чи помилитесь.
До речі, на конференції ACCU 2011 року Роджер Орр та Стів Лав представили сесію на тему: Деякі об'єкти є більш рівними, ніж інші - погляд на багато значень рівності, цінності та ідентичності . Їх слайди можна завантажити , як і Додаток Річарда Гарріса про рівність з плаваючою комою . Резюме: Будьте дуже обережні з operator==, тут дракони!
Перевантаження оператора - це дуже потужна семантична техніка, але її легко використовувати. В ідеалі ви повинні використовувати його лише в тих ситуаціях, коли з контексту зрозуміло, який вплив перевантажений оператор. Багато в чому a.union(b)це ясніше , ніж a+bта a*bє набагато більш неясним , ніж a.cartesianProduct(b), тим більше , що результат декартова твори буде , SetLike<Tuple<T,T>>а не SetLike<T>.
Справжні проблеми з перевантаженням оператора виникають тоді, коли програміст припускає, що клас буде вести себе в один спосіб, але він насправді веде себе по-іншому. Такого роду смислові зіткнення - це те, що я припускаю, що важливо намагатися уникати.