Каков наилучший способ реализации перегрузки оператора? - PullRequest
2 голосов
/ 22 апреля 2009

Из всего, что я узнал в C ++ (что не так уж много), перегрузка операторов кажется наиболее сложной. В общих чертах, когда лучше написать перегрузку оператора в качестве функции-друга? Когда я должен использовать explicilty *this? Всегда ли плохо использовать временный объект?

Ответы [ 4 ]

4 голосов
/ 22 апреля 2009

В перегрузке операторов abourt нет ничего волшебного - такие перегрузки - просто функции со странными именами. Таким образом, вы пишете перегрузки операторов так же, как вы пишете именованную функцию. На самом деле, часто хорошей идеей является сначала написать именованную функцию - вы всегда можете изменить ее на оператор позже.

Единственное, что вам нужно знать, это то, что компилятор использует пару ваших операторов:

  • operator = () при хранении вещей в коллекциях
  • оператор <() при сортировке / поиске вещей </li>
2 голосов
/ 22 апреля 2009

Нейл ответ правильный. Кроме того, эта ссылка предоставляет много полезной информации о том, когда, где, почему и как использовать различные типы перегрузки операторов в C ++.

В общем, я бы попытался придерживаться интуитивно понятных перегрузок - использование оператора '+' должно отражать нечто аналогичное сложению и т. Д. Если вы обнаружите, что сравниваете строки с оператором '+' или чем-то еще таким образом, вы, вероятно, должны вместо этого использовать стандартные функции.

1 голос
/ 22 апреля 2009

Первое правило перегрузки операторов: не перегружайте операторов, которые не имеют смысла. Например, оператор «+» может выглядеть хорошим выбором для добавления элементов в списки, но это не так: не все сочтут это использование логичным.

Что касается математических операторов, friend не требуется.

Типичный способ их определения (который учитывает симметрии и неявные преобразования) следующий:

struct T {
    T& operator+=(T const& rhs) {
        // the actual addition code
        return *this;
    }
};
T const operator+(T const& lhs, T const& rhs) {
     return T(lhs) += rhs;
};

Однако эта организация не приспособлена для таких операторов, как Matrix или Умножение Polynomial на оператор *=(T const&) не так тривиально. В этом В этом случае мы определяем operator*=(T const&) поверх operator*(T const&, T const&), и двоичный файл operator*() может быть сделан friend, если нет доступа к внутренним данным - это использование friend не является нарушением инкапсуляции но применение инкапсуляции - или в целях оптимизации.

Если вы действительно хотите исключить большинство временных значений, взгляните на шаблоны выражений (см. Blitz ++, boost.ublas, newmat, ...) или дождитесь ссылок на значения C ++ 0x.

0 голосов
/ 28 апреля 2009

Все перегрузки операторов как функции-члена принимают * это как lvalue, поэтому вам нужен друг в тех случаях, когда вы не хотите его, такие операторы потока перегрузки, как << и >>. В большинстве других случаев использование друзей заключается в разрыве принцип наименьших привилегий. Другой способ перегрузить оператор, о котором не говорилось, - использовать глобальную функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...