Thread: Please explain overloading arithmetic and relational operators

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    10

    Question Please explain overloading arithmetic and relational operators

    I vaguely understand the concept of overloading, but I do not understand how this applies to relational operators like <, <= and ==. I also do not understand how to overload addition, subtraction, multiplication and division, and I do not understand the logical reasoning behind overloading them.

    Could you please explain this to me? Thank you very much!

    ex: ( a*b + b*c ) / ( b*c ) Why is overloading better?*

    *This is not an assignment question, but a question relating to an assignment. The assignment assumes we already understand overloading, and as this is my only independent study class, well... if I'm my own teacher and I don't understand it, how am I supposed to do the homework?

    Can someone actually just write out how to overload the addition function? Just the simple stuff that I can't seem to grasp no matter how many websites I cruise. what comes in the .cpp file??

    I think it starts out as const operator+ ...
    but then I have no idea where it does from there in the header file, and the .cpp file is completely beyond me.

    Thanks.
    Last edited by aperson; 11-30-2008 at 04:54 PM. Reason: Narrowing question

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well not all operators make sense in all circumstances.

    For example, a string class could overload "+" to be concatenate two strings, but "*" doesn't make any sense at all.

    Likewise == would be a string comparison.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    Um... so that means...what? The "*" represents multiplication - sorry if that was confusing.

    I'm trying to understand what it means to overload something like addition. How does one even go about that?

    I am so lost... ^^;

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > The "*" represents multiplication
    Maybe.

    In the string example, "+" means add one string onto the end of another. It's a slightly different sense of the word "add" (and not a mathematical one). But it's one which programmers are familiar with that it makes sense.

    Take a more concrete numeric example, say roman numerals.
    roman a("X");
    roman b("V");
    roman c = a * b;
    cout << c << endl; // outputs L

    Here is does make sense to overload all the numeric operators, because you're dealing with what is a numeric type, which is expressed in a non-conventional way.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    Right. that makes sense....

    Since I am dealing with numbers (rational fractions), how would i express this? Say, with numbers a and b.

    Thank you so much.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Overloading, in its original conception, was intended to allow the writer of a user-defined type - say, string or rational - make all those operators that exist for built-in types work for his type, too. The key idea here is that the semantics of those operators should change as little as possible. Same operator, same meaning, different operands.

    Thus, it's a bit difficult to understand the question. The idea behind operator overloading is that you express multiplication as a*b, no matter what a and b are. That's the entire idea.

    Later, operator overloading got used for very different purposes, but that's a different chapter.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    Well, it's a class assignment - what can I say?

    I don't really understand the point of it myself, but I'm not the professor...

    If I had two integers, a and b, how would I add them like that?

    I've searched high and low online (after exhausting my book and associated powerpoints) and can't find a single example that makes any sense. I'm sure if I see something simple, like addition, I can figure out the rest of it.

    Thank you so much!

  8. #8
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Quote Originally Posted by aperson View Post
    Right. that makes sense....

    Since I am dealing with numbers (rational fractions), how would i express this? Say, with numbers a and b.

    Thank you so much.
    If you are indeed working with a custom class for fractions, you would overload the + operator so it would return a new instance of the fraction class, where the fraction is the result of the addititon. Pseudo-code:

    Code:
    overload +operator(Fraction f1, Fraction f2)
    {
         return new Fraction(f1.numerator + f2.numerator, f1.denominator + f2.denominator);
    }
    
    // Constructor
    
    Fraction(int numerator, int denominator)
    {
         _numerator = numerator;
         _denominator = denominator;
    }
    Convert this to real C++ code, and write the appropriate class, this will allow you to actually add the the fractions as you would add any other basic type, integers, doubles etc.
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    ( a*b + b*c ) / ( b*c ) Why is overloading better?
    Operator overloading is mainly syntactical sugar, but without it that line would read:
    Code:
    div(sum(mult(a, b), mult(b, c)), mult(b, c))
    It is also important when templates comes to play. For example, how would you write a function that would work for pointers and classes (iterators) if the iterators didn't provide the similar interface and operators as pointers? (like most functions in <algorithms>)

    Overloading + usually looks like this:
    Code:
    MyClass operator+(const MyClass& lhv, const MyClass& rhv); //non-member
    You can't overload operators for built-in types only. You can't take int a and int b and make + means something different for them.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    No no no... not with fractions. I can do that part of it. (Yay for me - I figured one part of this bloody assignment out!)

    I just need to know how to add two integers. That's it. (And given that I don't understand your pseudo-code, I am hopeless...)

    Thank you.

  11. #11
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    What does the MyClass mean? What I mean is, if my class is titled RationalADT, then would MyClass be replaced with RationalADT? And lhv and rhv - left and right hand values, or did I just make that up?

    And would that overload it? Could I output that with cout, as in
    Code:
    cout<<firstFractionSet.operator+(a, b);
    and it would output, 5 or something?

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    MyClass is your class, whatever you called it. You very rarely would actually say "operator+(a,b)" -- the whole point of the thing is that you can use the traditional operator notation and just say a+b. You would be able to send it to cout provided you've defined << for your class as well.

  13. #13
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I just need to know how to add two integers. That's it.

    The signature for operators returning temporaries (usu.: +, -, *, etc) is generally going to be:

    Code:
    template < typename Type >
    Number< Type >
    operator XYZ( Number< Type > const&, Number< Type > const& ); // return a temporary object
    Otherwise, for non-const transformations (usu.: +=, -=, *=, etc):

    Code:
    template < typename Type >
    Number< Type >&
    operator XYZ( Number< Type >&, Number< Type > const& ); // return the non-const object
    The latter are often written as member functions.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  14. #14
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    Yes, ok. Well, does "very rarely" mean that it won't work, or does it mean that I've completely skated around the issue?

    And what do you mean "defined << for [my] class?" Isn't "<<" already defined somewhere in the vast wonderful libraries that I take for granted?

  15. #15
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    "Very rarely" means I've seen (if I recall correctly) one legitimate use where writing "a+b" wouldn't work, in about three years.

    Nothing in your class is already defined somewhere. The bits of it are already defined -- you can take printing an integer for granted, and printing a '/' character. But printing a Rational is not (yet) defined.

Popular pages Recent additions subscribe to a feed

Tags for this Thread