Мне хочется сказать, что узнать об операторе нечего
перегрузки; перегруженные операторы - просто забавные именованные функции. Какие
Вы должны узнать, когда перегрузка уместна, и когда это
не. Некоторые идиомы более или менее стандартны: числовые типы перегружаются
соответствующие числовые операторы (+
и т. д.), перегрузка умных указателей
указатель ops (*
и ->
), типы контейнеров, которые поддерживают индексацию
перегрузка []
, а перегрузка функциональных объектов ()
. И это о
это для особых случаев. И хотя это, возможно, злоупотребление, если вы
определить итератор, вы хотите, чтобы он поддерживал стандартный итератор
идиома (что означает ++
, *
, ->
и ==
/ !=
).
В дополнение к этому есть три оператора, которые будут перегружены
для многих различных типов классов: назначение выполняется с использованием =
, и
вставка и извлечение из потоков осуществляется с помощью <<
и >>
.
Если вы хотите, чтобы ваш класс поддерживал любой из них, вы должны использовать
перегрузки. И сравнение использует ==
и !=
для равенства и <
,
<=
, >
и >=
для неравенства. Но не перегружайте из-за неравенства
если это не семантически значимо. Лучше предоставить
функция явного упорядочения для использования с std::map
и std::set
than
вводить читателей в заблуждение, что вы определили их как семантически
значительный порядок. Возможно, вы захотите специализировать std::less
на вашем
класс в этом случае; <
не будет работать или будет иметь неправильную семантику
для использования в качестве ключа, но std::less
определит произвольный порядок
который будет. И хотя это не перегрузка операторов, если тип
использовать в качестве ключа в ассоциативных контейнерах, вы также хотите предоставить
функция hash_code
и экземпляр struct std::hash
.
Во многих случаях лучше определить перегрузку в терминах еще нескольких
глобальная функция: например: я использую compare
(возвращая int
меньше
чем, равно или больше 0) для неравенства; Я определю общественность
функция compare
в классе, а затем получить из чего-то вроде:
template<typename T>
struct ComparisonOperators
{
friend bool operator==( T const& lhs, T const& rhs )
{
return lhs.compare() < 0;
}
// ...
// The same for the other five operators.
};
(Моя реализация на самом деле несколько сложнее, так как она использует
метапрограммирование для использования isEqual
для ==
и !=
, если класс обеспечивает
она.)
Я использую похожую технику для бинарных арифметических операторов, определяя
+
в терминах +=
и т. Д. Я также использую его для ввода-вывода, определяя <<
в терминах
print
и >>
в пересчете на parse
; это в основном полезно, когда
операторы должны быть полиморфными.