2012-04-25 3 views
1

Можно создать дубликат:
Operator overloading
Operator overloading : member function vs. non-member function?Зачем плохой практике перегружать оператор <в качестве функции-члена?

После многих лет, очевидно, злоупотребляя этой конструкции кто-то указал мне, что это плохая практика:

class SomeClass 
{ 
    ... 
    bool operator<(const SomeClass& other) const; 
}; 

в то время как это хорошая практика:

class SomeClass 
{ 
    ... 
}; 
bool operator<(const SomeClass& a, const SomeClass& b); 

Но я не могу на всю жизнь выяснить, почему и не могу найти никаких документов о различии. Может кто-то указать мне верное направление?

+1

См. Http://stackoverflow.com/questions/4622330/operator-overloading-member-function-vs-non-member-function – dirkgently

+0

Спасибо, думаю, я специально искал операторов сравнения и пропустил его. – smocking

+1

[Решение между членом и нечленом] (http://stackoverflow.com/questions/4421706/operator-overloading/4421729#4421729). –

ответ

3

Первое, что не имеет преимущества при реализации оператора как функции-члена, и в его использовании могут быть преимущества в качестве свободной функции. В частности, функция-член не симметрична по отношению к типам двух операндов, левая часть (lhs) должна быть точного типа класса, на котором она вызывается, тогда как правая часть - side (rhs) может использовать неявные преобразования. В случае операторов свободных функций одни и те же преобразования могут быть применены к lhs и rhs.

struct SomeClass { 
    SomeClass(int value); 
    bool operator<(SomeClass const &) const; 
}; 
bool operator>(SomeClass const &, SomeClass const &); 
int main() { 
    SomeClass x(10); 
    x < 100;    // Fine, lhs is SomeClass 
    // 100 < x;   // Error, no operator< can take int as lhs and SomeClass 
    x > 100;    // Fine 
    100 > x;    // Also fine, lhs can take the same implicit conversions 
} 

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

Я написал некоторое время назад о перегрузке оператора here, вы можете найти там некоторые предложения.

+0

Я бы посчитал неявное преобразование в качестве недостатка в некоторых ситуациях (но опять же я попытался бы предотвратить его в первую очередь, имея явный конструктор). Если ваш тип - это другой числовой тип, то неявное преобразование, вероятно, ОК, но другие типы, которые я должен был бы рассматривать в каждом конкретном случае. –

+0

@ LokiAstari: Согласиться с тем, что неявные преобразования следует избегать, но если таковой существует, не имеет смысла вести себя по-разному в левой и правой сторонах операции, то есть проблема с неявными преобразованиями существует в обоих случаях, но в одном из них он последователен. Как я и пытался сказать, наличие свободной функции никогда не повредит и может помочь в некоторых случаях (где неявные преобразования желательны). –

+0

Некоторые из вещей, которые я мог найти, говорили о симметрии и инкапсуляции класса, но я предполагаю, что неявные преобразования являются фактическим практическим преимуществом. Только слышал о перегрузке оператора, не являющегося членом в последнее время на SO, и был довольно удивлен, что оператор-член <был отклонен как «плохая практика» и что-то, что вам «не нужно делать», тем более, что это был единственный способ, которым я знал, и использовал его в течение многих лет по всему моему коду. Приятно знать, что это не так плохо, как я боялся. – smocking

Смежные вопросы