Search

9.6 — Overloading the comparison operators

Overloading the comparison operators is comparatively simple (see what I did there?), as they follow the same patterns as we’ve seen in overloading other operators.

Because the comparison operators are all binary operators that do not modify their left operands, we will make our overloaded comparison operators friend functions.

Here’s an example Car class with an overloaded operator== and operator!=.

The code here should be straightforward. Because the result of operator!= is the opposite of operator==, we define operator!= in terms of operator==, which helps keep things simpler, more error free, and reduces the amount of code we have to write.

(and of course, we really shouldn’t be comparing floats using operator == or != anyway)

It doesn’t really make sense to overload operator> or operator< for the Point class. What does it mean for a Point to be greater or less than another Point? Greater than or less than isn’t a concept we normally apply to Points, so it’s better not to include those operators in the Point class, because the results of the operators (whatever you define them to be) would not be intuitive.

Here’s a different example with an overloaded operator>, operator<, operator>=, and operator<=:

This is also pretty straightforward.

Note that there is some redundancy here as well. operator> and operator<= are logical opposites, so one could be defined in terms of the other. operator< and operator>= are also logical opposites, and one could be defined in terms of the other. In this case, I chose not to do so because the function definitions are so simple, and the comparison operator in the function name line up nicely with the comparison operator in the return statement.

Quiz time

1) For the Cents example above, rewrite operators < and <= in terms of other overloaded operators.

Show Solution

9.7 -- Overloading the increment and decrement operators
Index
9.5 -- Overloading unary operators +, -, and !

27 comments to 9.6 — Overloading the comparison operators

  • Ameerah

    thanks Alex very mutch i love you totorile

    simple &easy

  • j.howard

    Great tutorial as usual. Just as an idea the < and > operators could be used to compare the magnitude of the vector from the origin to the point in the Point class.

  • Rahul

    Why can’t I overload operator ‘~=’ same way I overload ‘==’? I want it to have same definition as ‘!=’.

    It gives error "declaration of ‘operator~’ as non-function". Is it an error with my syntax?

    I read somewhere that C++ overloads operators whose definitions are already known? Is that true? For example can’t overload definition of ‘#’ operator. Or define my own operator.

    my code:

    • Alex

      In C++, you can only overload operators that already exist in C++. ~= isn’t an operator that naturally exists in C++, so you can’t overload it.

  • "operator> and operator<= are logical opposites, so one could be defined in terms of the other. operator< and operator>= are also logical opposites"

    shouldn’t it be:

    "operator> and operator< are logical opposites, so one could be defined in terms of the other. operator<= and operator>= are also logical opposites"

    (last paragraph)

  • N.Abb

    Why we have to overload relational operators in pairs ?
    like if I overload == I must overload !=
    Thanks

    • Alex

      You don’t have to. However, since one can be defined in terms of the other, it’s almost trivial to write the second after you have the first.

    • Darren

      C++ is sweet with syntax sugar; it’s not needed but it is nice to have.

      A function or operator that has a "positive" effect on a class should in best practice, and where possible, come with a "negative" twin (note this is not a requirement). For example,
      consider a class that represents bank accounts. If there is a function/operator that allows users to deposit cash, then there should be a opposite function/operator that allows them to withdraw their cash (unless the bank is particularly devious). Or if you have an operator to sum two vectors, you’d expect to have an operator to find the difference between two vectors. There are exceptions. For example, you can multiply two matrices, but matrix division is undefined (instead this would be matrix factorisation).

  • j_nick

    This is also pretty straightforward. Note that there is some redundancy here as well. operator> and operator<= are logical opposites, so one could be defined in terms of the other

  • j_nick

    operator> and operator<= are logical opposites, so one could be defined in terms of the other. operator< and operator>= are also logical opposites
    const ?

    • N.ab

      Hi Alex : is correct ?…

      • Alex

        Yes. If two operators are logical opposites, one can be defined as the negation of the other.

        If the implementation of the operator is trivial, like the examples in the lesson, this probably isn’t worth doing (it’s easier to just implement it).

        If the implementation of the operator is more complicated, then this can be worth doing as a way to reduce redundant code.

  • nick

    Hi Alex;
    Should not the ! operator overloaded

    • Alex

      It could be implemented that way, and if operator > is complicated, I’d recommend it, to reduce the amount of redundant code.

      However, when the implementation of the comparison operators is trivial, it’s easier (and more understandable) to just implement them individually.

  • Valentino

    Why does (Cents > int) use my overloaded operator (Cents > Cents)?
    Thanks

    • Alex

      Because one of your operands is an object of type Cents, C++ will first look to see if there is an operator where both operands match. In this case, there isn’t. Next, the compiler will try to see if it can promote or convert types to make the operands match. In this case, because you have a Cents constructor that takes an int, the compiler will use this constructor to create a Cents object from the int.

      It’s essentially implicitly converting the if statement to this:

      • Valentino

        Thank you for your response. Is it possible to tell C++ that it should not have to do that so I will get an error on compile?

        • Alex

          Yes, put the explicit keyword before your constructor name. This will prevent C++ from using it for type conversions.

  • Chandra

    Thanks Alex. Such a nice website/tutorial.
    I had a question.
    I was wondering if comparison operators MUST be defined as friend functions, if both the operands are of same type. a member function with right operand as the required class type should be fine right!

    i agree, if the left operand is of different type, then we might have to go for a Friend function.

    And, your text: "Because the comparison operators are all binary operators that do not modify their operands, we will make our overloaded comparison operators friend functions." confuses me.

    is it that, "operators do not modify operands" the criteria to define it as a friend function? Can you please explain?

    • Alex

      You can define a comparison operator as a member function so long as you can modify the class of the left operand.

      “operators do not modify operands” is not a criteria to define an operator as a friend function, but it’s generally easier to understand what the operator is doing when written in “friend mode” rather than “member mode” since the left operand doesn’t become the implicit *this object. The friend version provides better symmetry since both operands are function parameters.

      Similarly, writing operators in “member mode” is better when the operator does modify the class (e.g. operator+=) because then it’s easier to tell what is getting modified (*this) vs. what’s a parameter.

  • Sagar Sanghavi

    Hi Alex,

    In the quiz question, did you intend the answer to be this:

    instead of:

    Because only then we are ensuring that we re-use the above function, i.e. "operator>=" correct?

  • Nyap

    shouldn’t quiz time be on a new line

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter

  

  

  

twelve + ten =