Перегрузка оператора - PullRequest
4 голосов
/ 06 июля 2010

С точки зрения языкового дизайна, какой тип практики поддерживает перегрузку операторов?

Каковы плюсы и минусы (если есть)?

Ответы [ 5 ]

16 голосов
/ 06 июля 2010

РЕДАКТИРОВАТЬ: было упомянуто, что std::complex является гораздо лучшим примером, чем std::string для "хорошего использования" перегрузки операторов, поэтому я также включаю пример этого:

std::complex<double> c;
c = 10.0;
c += 2.0;
c = std::complex<double>(10.0, 1.0);
c = c + 10.0;

Помимо синтаксиса конструктора, он выглядит и действует так же, как и любой другой встроенный тип.


Основным преимуществом является то, что вы можете создавать новые типы, которые действуют как встроенныетипы.Хорошим примером этого является std::string (см. Выше для лучшего примера) в C ++.Который реализован в библиотеке и не является базовым типом.Тем не менее, вы можете написать что-то вроде:

std::string s = "hello"
s += " world";
if(s == "hello world") {
    //....
}

Недостатком является то, что им легко злоупотреблять.Неправильный выбор при перегрузке оператора может привести к случайно неэффективному или нечеткому коду.Представьте себе, если std::list имел operator[].У вас может возникнуть желание написать:

for(int i = 0; i < l.size(); ++i) {
    l[i] += 10;
}

это алгоритм O (n ^ 2) !Уч.К счастью, std::list не имеет operator[], поскольку предполагается, что это эффективная операция.

13 голосов
/ 06 июля 2010

Первоначальный драйвер, как правило, математика.Программисты хотят добавлять векторы и кватернионы, записывая a + b и умножая матрицы на векторы с M * v.

. Он имеет гораздо более широкий охват, чем этот.Например, интеллектуальные указатели синтаксически выглядят как обычные указатели, потоки могут выглядеть как каналы Unix, а различные пользовательские структуры данных могут использоваться, как если бы они были массивами (со строками в качестве индексов, даже!).

ОбщееПринцип перегрузки заключается в том, чтобы позволить разработчикам библиотеки беспрепятственно улучшать язык.Это и сила, и проклятие.Он предоставляет очень мощный способ сделать язык более богатым, чем он есть в готовом виде, но он также очень уязвим для злоупотреблений (в большей степени, чем многие другие функции C ++).

6 голосов
/ 06 июля 2010

Плюсы: вы можете получить код, который проще читать.Мало кто будет утверждать, что:

BigDecimal a = x.add(y).divide(z).plus(m.times(n));

так же легко прочитать, как и

BigDecimal a = ((x + y) / z) + (m * n); // Brackets added for clarity

Минусы: сложнее сказать, что называется.Кажется, я помню, что в C ++ оператор вида

a = b[i];

может в итоге выполнить 7 пользовательских операций, хотя я не могу вспомнить, что они все из себя представляют.Возможно, я немного «выключен» в этом примере, но принцип верен - перегрузка операторов и пользовательские преобразования могут «скрыть» код.

1 голос
/ 06 июля 2010

Вы можете сделать некоторые интересные трюки с синтаксисом (то есть потоки в C ++), и вы можете сделать некоторый код очень кратким. Однако вы можете сделать код очень трудным для отладки и понимания. Вы должны постоянно быть настороже относительно эффектов различных операторов различных типов объектов.

0 голосов
/ 06 июля 2010

Вы можете считать перегрузку оператора своего рода перегрузкой метода / функции. Это часть полиморфизма в объектно-ориентированном языке.

С перегрузкой каждый класс объектов работает как примитивные типы, что делает классы более естественными для использования, просто как 1 + 2.

Скажем, комплексное число, класс, Комплекс. Комплекс (1,2i) + Комплекс (2,3i) дает комплекс (3,5i). Комплекс 5 + (3, 2i) дает комплекс (8, 2i). Комплекс (2, 4i) + -1,8 дает комплекс (0,2, 4i).

Так гораздо проще использовать класс. Если перегрузка оператора отсутствует, вы должны использовать кучу методов класса, чтобы обозначить «добавить» и сделать нотацию неуклюжей.

Перегрузка оператора должна быть тщательно определена; в противном случае приходит смятение. Например, оператор «+» является естественным для добавления чисел, времени, даты или объединения массива или текста. Добавление оператора «+» в класс Mouse или Car может не иметь никакого смысла. Иногда некоторые перегрузки могут не казаться естественными для некоторых людей. Например, Array (1,2,3) + Array (3,4,5). Некоторые могут ожидать Array (4,6,8), но некоторые ожидают Array (1,2,3,3,4,5).

...