Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing objects using bool operator==

So, after reading some SO questions and answers, i still doesn't understand why use

friend bool operator==( BaseClass const &left, BaseClass const &right )

instead of

bool operator==( BaseClass const &right )

right now I have something like this http://pastebin.com/pKsTabC0 (Fixed) - and it seems to work fine. But maybe I'm missing something? Any Suggestions?

Update 1

Ok i changed the source to make it work right http://ideone.com/fIAmB. Removed unnecessary virtual and added const. Still i dont understand why to use friends...

like image 582
DmitryM Avatar asked Jul 24 '12 14:07

DmitryM


2 Answers

Your derived function doesn't have the same signature as the parent operator, so it hides the parent comparison rather than overriding it. This means that you can't make use of the virtual-ness anyway since the static type of the left hand argument determines the function that's called.

That's why the normal method for virtual comparison is a non-member equality operator that dispatches to a virtual comparison function in the base class.

Do consider your specific need for virtual comparison though as it may be a design smell that there's an alternate design you could use instead.

Also note that member comparison (equality in this case) operators should usually be const.

EDIT: It seems that you may only care about comparison based on the static type of the left hand argument, which should be an easier problem. In this case your code handles all cases except where the left hand argument is a type implicitly converts to a Base or Derived by some mechanism other than inheritance (conversion operator or converting constructor). If you don't care about those cases, then the member equality is fine.

As one final note, if the comparison could be done entirely through the public interface, we (almost) always prefer non-member, non-friend functions regardless of whether or not it's an operator.

EDIT2 (A really quick overview of non-member, non-friend):

For example suppose your class has a public key method, and if the keys of two instances are equal you want to call the objects equal. Then, without using friends or a member equality operator, you can write your equality standalone:

bool operator==(const MyType& left, const MyType& right)
{
    return left.key() == right.key();
}
like image 100
Mark B Avatar answered Oct 02 '22 11:10

Mark B


There's nothing wrong per se with the member function, but the free function is more generic. The member function is forced to have the left-hand side operand be of type BaseClass or a child type, while the free function accepts any types that are implicitly convertible to BaseClass, not just types that are part of the inheritance tree.

like image 44
Paul Manta Avatar answered Oct 02 '22 11:10

Paul Manta