Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an Object by reference to Overloaded Operator - C++

Quite new to C++. I have seen people usually pass objects by reference in operator overloading. Well, I can't figure out when it is really necessary. As in the code below, if I remove ampersand in declaration of object c1 and c2 in operator+, still I'll get the same result. Is there any reason to pass-by-reference in this case when we do not want to modify c1 or c2?

#include <iostream>

class Keys
{
private:
    int m_nKeys;

public:
    Keys(int nKeys) { m_nKeys = nKeys; }

    friend Keys operator+(const Keys &c1, const Keys &c2);

    int GetKeys() { return m_nKeys; }
};


Keys operator+(const Keys &c1, const Keys &c2)
{
    return Keys(c1.m_nKeys + c2.m_nKeys);
}

int main()
{
    Keys cKeys1(6);
    Keys cKeys2(8);
    Keys cKeysSum = cKeys1 + cKeys2;
    std::cout << "There are " << cKeysSum.GetKeys() << " Keys." << std::endl;
    system("PAUSE");
    return 0;
}
like image 428
QuestionMark Avatar asked Oct 08 '14 07:10

QuestionMark


People also ask

Why do we pass by reference in operator overloading?

Advantages of passing by reference: It allows us to have the function change the value of the argument, which is sometimes useful. Because a copy of the argument is not made, it is fast, even when used with large structs or classes. We can pass by const reference to avoid unintentional changes.

Can you overload operators in C?

RE your edits: No, you can't. There is no such thing as operator overloading in C. You cannot define custom operators to work with your structs, in any way, at all, in C. Operator overloading is something you do in C++, it has nothing what so ever to do with C.

Which operator is overloaded for CIN?

Notes: The relational operators ( == , != , > , < , >= , <= ), + , << , >> are overloaded as non-member functions, where the left operand could be a non- string object (such as C-string, cin , cout ); while = , [] , += are overloaded as member functions where the left operand must be a string object.


3 Answers

Operators are just like ordinary functions, just with "fancy" names :)
(e.g. operator+() instead of sum())

So, the same parameter passing rules that you apply to functions, can be applied to overloaded operators as well.

In particular, when you have a parameter that is not cheap to copy (e.g. an int, a float, are examples of cheap to copy parameters; a std::vector, a std::string, are examples of not cheap to copy parameters), and you observe this parameter inside your method (i.e. it's an input read-only parameter), then you can pass it by const reference (const &).

In this way, basically it's just like the address of the original argument is passed to the function, so there is no deep-copy involved. Deep-copies can be very expensive, e.g. think of a vector with a big number of elements.

So, to recap, you pass by const reference when:

  1. the parameter just is not cheap to copy (e.g. for ints, float, etc. just don't bother: passing by value is just fine)
  2. the parameter is observed in the function/operator implementation (i.e. it's an input read-only parameter)
like image 190
Mr.C64 Avatar answered Oct 16 '22 13:10

Mr.C64


If you pass by reference then there is no copy of the object made, which for more complicated classes could greatly improve performance.

In this case the performance cost may be marginal, and it's conceivable the compiler could optimise it all out, but it's still worth doing. Later the Keys class may change into something more complex.

like image 3
David Sykes Avatar answered Oct 16 '22 12:10

David Sykes


Advantages of passing by reference:

  1. It allows us to have the function change the value of the argument, which is sometimes useful.
  2. Because a copy of the argument is not made, it is fast, even when used with large structs or classes.
  3. We can pass by const reference to avoid unintentional changes.
  4. We can return multiple values from a function.

Disadvantages of passing by reference:

  1. Because a non-const reference can not be made to a literal or an expression, reference arguments must be normal variables.
  2. It can be hard to tell whether a parameter passed by reference is meant to be input, output, or both.
  3. It’s impossible to tell from the function call that the argument may change. An argument passed by value and passed by reference looks the same. We can only tell whether an argument is passed by value or reference by looking at the function declaration. This can lead to situations where the programmer does not realize a function will change the value of the argument.
  4. Because references are typically implemented by C++ using pointers, and dereferencing a pointer is slower than accessing it directly, accessing values passed by reference is slower than accessing values passed by value.

You can read the below:

http://www.cs.fsu.edu/~myers/c++/notes/references.html

like image 1
Roy Avatar answered Oct 16 '22 13:10

Roy