Some of the most commonly used operators in C++ are the arithmetic operators -- that is, the plus operator (+), minus operator (-), multiplication operator (*), and division operator (/). Note that all of the arithmetic operators are binary operators -- meaning they take two operands -- one on each side of the operator. All four of these operators are overloaded in the exact same way.

It turns out that there are three different ways to overload operators: the member function way, the friend function way, and the normal function way. In this lesson, we’ll cover the friend function way (because it’s more intuitive for most binary operators). Next lesson, we’ll discuss the normal function way. Finally, in a later lesson in this chapter, we’ll cover the member function way. And, of course, we’ll also summarize when to use each in more detail.

Overloading operators using friend functions

Consider the following trivial class:

1 2 3 4 5 6 7 8 9 |
class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } int getCents() const { return m_cents; } }; |

The following example shows how to overload operator plus (+) in order to add two “Cents” objects together:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <iostream> class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } // add Cents + Cents using a friend function friend Cents operator+(const Cents &c1, const Cents &c2); int getCents() const { return m_cents; } }; // note: this function is not a member function! Cents operator+(const Cents &c1, const Cents &c2) { // use the Cents constructor and operator+(int, int) // we can access m_cents directly because this is a friend function return Cents(c1.m_cents + c2.m_cents); } int main() { Cents cents1{ 6 }; Cents cents2{ 8 }; Cents centsSum{ cents1 + cents2 }; std::cout << "I have " << centsSum.getCents() << " cents.\n"; return 0; } |

This produces the result:

I have 14 cents.

Overloading the plus operator (+) is as simple as declaring a function named operator+, giving it two parameters of the type of the operands we want to add, picking an appropriate return type, and then writing the function.

In the case of our Cents object, implementing our operator+() function is very simple. First, the parameter types: in this version of operator+, we are going to add two Cents objects together, so our function will take two objects of type Cents. Second, the return type: our operator+ is going to return a result of type Cents, so that’s our return type.

Finally, implementation: to add two Cents objects together, we really need to add the m_cents member from each Cents object. Because our overloaded operator+() function is a friend of the class, we can access the m_cents member of our parameters directly. Also, because m_cents is an integer, and C++ knows how to add integers together using the built-in version of the plus operator that works with integer operands, we can simply use the + operator to do the adding.

Overloading the subtraction operator (-) is simple as well:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <iostream> class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } // add Cents + Cents using a friend function friend Cents operator+(const Cents &c1, const Cents &c2); // subtract Cents - Cents using a friend function friend Cents operator-(const Cents &c1, const Cents &c2); int getCents() const { return m_cents; } }; // note: this function is not a member function! Cents operator+(const Cents &c1, const Cents &c2) { // use the Cents constructor and operator+(int, int) // we can access m_cents directly because this is a friend function return Cents(c1.m_cents + c2.m_cents); } // note: this function is not a member function! Cents operator-(const Cents &c1, const Cents &c2) { // use the Cents constructor and operator-(int, int) // we can access m_cents directly because this is a friend function return Cents(c1.m_cents - c2.m_cents); } int main() { Cents cents1{ 6 }; Cents cents2{ 2 }; Cents centsSum{ cents1 - cents2 }; std::cout << "I have " << centsSum.getCents() << " cents.\n"; return 0; } |

Overloading the multiplication operator (*) and the division operator (/) is as easy as defining functions for operator* and operator/ respectively.

Friend functions can be defined inside the class

Even though friend functions are not members of the class, they can still be defined inside the class if desired:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <iostream> class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } // add Cents + Cents using a friend function // This function is not considered a member of the class, even though the definition is inside the class friend Cents operator+(const Cents &c1, const Cents &c2) { // use the Cents constructor and operator+(int, int) // we can access m_cents directly because this is a friend function return Cents(c1.m_cents + c2.m_cents); } int getCents() const { return m_cents; } }; int main() { Cents cents1{ 6 }; Cents cents2{ 8 }; Cents centsSum{ cents1 + cents2 }; std::cout << "I have " << centsSum.getCents() << " cents.\n"; return 0; } |

We generally don’t recommend this, as non-trivial function definitions are better kept in a separate .cpp file, outside of the class definition. However, we will use this pattern in future tutorials to keep the examples concise.

Overloading operators for operands of different types

Often it is the case that you want your overloaded operators to work with operands that are different types. For example, if we have Cents(4), we may want to add the integer 6 to this to produce the result Cents(10).

When C++ evaluates the expression `x + y`

, x becomes the first parameter, and y becomes the second parameter. When x and y have the same type, it does not matter if you add x + y or y + x -- either way, the same version of operator+ gets called. However, when the operands have different types, x + y does not call the same function as y + x.

For example, `Cents(4) + 6`

would call operator+(Cents, int), and `6 + Cents(4)`

would call operator+(int, Cents). Consequently, whenever we overload binary operators for operands of different types, we actually need to write two functions -- one for each case. Here is an example of that:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include <iostream> class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } // add Cents + int using a friend function friend Cents operator+(const Cents &c1, int value); // add int + Cents using a friend function friend Cents operator+(int value, const Cents &c1); int getCents() const { return m_cents; } }; // note: this function is not a member function! Cents operator+(const Cents &c1, int value) { // use the Cents constructor and operator+(int, int) // we can access m_cents directly because this is a friend function return { c1.m_cents + value }; } // note: this function is not a member function! Cents operator+(int value, const Cents &c1) { // use the Cents constructor and operator+(int, int) // we can access m_cents directly because this is a friend function return { c1.m_cents + value }; } int main() { Cents c1{ Cents{ 4 } + 6 }; Cents c2{ 6 + Cents{ 4 } }; std::cout << "I have " << c1.getCents() << " cents.\n"; std::cout << "I have " << c2.getCents() << " cents.\n"; return 0; } |

Note that both overloaded functions have the same implementation -- that’s because they do the same thing, they just take their parameters in a different order.

Another example

Let’s take a look at another example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
#include <iostream> class MinMax { private: int m_min; // The min value seen so far int m_max; // The max value seen so far public: MinMax(int min, int max) { m_min = min; m_max = max; } int getMin() const { return m_min; } int getMax() const { return m_max; } friend MinMax operator+(const MinMax &m1, const MinMax &m2); friend MinMax operator+(const MinMax &m, int value); friend MinMax operator+(int value, const MinMax &m); }; MinMax operator+(const MinMax &m1, const MinMax &m2) { // Get the minimum value seen in m1 and m2 int min{ m1.m_min < m2.m_min ? m1.m_min : m2.m_min }; // Get the maximum value seen in m1 and m2 int max{ m1.m_max > m2.m_max ? m1.m_max : m2.m_max }; return { min, max }; } MinMax operator+(const MinMax &m, int value) { // Get the minimum value seen in m and value int min{ m.m_min < value ? m.m_min : value }; // Get the maximum value seen in m and value int max{ m.m_max > value ? m.m_max : value }; return { min, max }; } MinMax operator+(int value, const MinMax &m) { // call operator+(MinMax, int) return { m + value }; } int main() { MinMax m1{ 10, 15 }; MinMax m2{ 8, 11 }; MinMax m3{ 3, 12 }; MinMax mFinal{ m1 + m2 + 5 + 8 + m3 + 16 }; std::cout << "Result: (" << mFinal.getMin() << ", " << mFinal.getMax() << ")\n"; return 0; } |

The MinMax class keeps track of the minimum and maximum values that it has seen so far. We have overloaded the + operator 3 times, so that we can add two MinMax objects together, or add integers to MinMax objects.

This example produces the result:

Result: (3, 16)

which you will note is the minimum and maximum values that we added to mFinal.

Let’s talk a little bit more about how “MinMax mFinal = m1 + m2 + 5 + 8 + m3 + 16” evaluates. Remember that operator+ has higher precedence than operator=, and operator+ evaluates from left to right, so m1 + m2 evaluate first. This becomes a call to operator+(m1, m2), which produces the return value MinMax(8, 15). Then MinMax(8, 15) + 5 evaluates next. This becomes a call to operator+(MinMax(8, 15), 5), which produces return value MinMax(5, 15). Then MinMax(5, 15) + 8 evaluates in the same way to produce MinMax(5, 15). Then MinMax(5, 15) + m3 evaluates to produce MinMax(3, 15). And finally, MinMax(3, 15) + 16 evaluates to MinMax(3, 16). This final result is then assigned to mFinal.

In other words, this expression evaluates as “MinMax mFinal = (((((m1 + m2) + 5) + 8) + m3) + 16)”, with each successive operation returning a MinMax object that becomes the left-hand operand for the following operator.

Implementing operators using other operators

In the above example, note that we defined operator+(int, MinMax) by calling operator+(MinMax, int) (which produces the same result). This allows us to reduce the implementation of operator+(int, MinMax) to a single line, making our code easier to maintain by minimizing redundancy and making the function simpler to understand.

It is often possible to define overloaded operators by calling other overloaded operators. You should do so if and when doing so produces simpler code. In cases where the implementation is trivial (e.g. a single line) it’s often not worth doing this, as the added indirection of an additional function call is more complicated than just implementing the function directly.

Quiz time

Question #1

a) Write a class named Fraction that has a integer numerator and denominator member. Write a print() function that prints out the fraction.

The following code should compile:

1 2 3 4 5 6 7 8 9 10 11 12 |
#include <iostream> int main() { Fraction f1{ 1, 4 }; f1.print(); Fraction f2{ 1, 2 }; f2.print(); return 0; } |

This should print:

1/4 1/2

b) Add overloaded multiplication operators to handle multiplication between a Fraction and integer, and between two Fractions. Use the friend function method.

Hint: To multiply two fractions, first multiply the two numerators together, and then multiply the two denominators together. To multiply a fraction and an integer, multiply the numerator of the fraction by the integer and leave the denominator alone.

The following code should compile:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostream> int main() { Fraction f1{2, 5}; f1.print(); Fraction f2{3, 8}; f2.print(); Fraction f3{ f1 * f2 }; f3.print(); Fraction f4{ f1 * 2 }; f4.print(); Fraction f5{ 2 * f2 }; f5.print(); Fraction f6{ Fraction{1, 2} * Fraction{2, 3} * Fraction{3, 4} }; f6.print(); return 0; } |

This should print:

2/5 3/8 6/40 4/5 6/8 6/24

c) Why does the program continue to work correctly if we remove the operators for integer multiplication from the previous solution?

1 2 3 |
// We can remove these operators, and the program continues to work Fraction operator*(const Fraction &f1, int value); Fraction operator*(int value, const Fraction &f1); |

d) If we remove the `const`

from the `Fraction * Fraction`

operator, the following line from the `main`

function no longer works. Why?

1 2 3 4 5 |
// The non-const multiplication operator looks like this Fraction operator*(Fraction &f1, Fraction &f2) // This doesn't work anymore Fraction f6{ Fraction{1, 2} * Fraction{2, 3} * Fraction{3, 4} }; |

e) Extra credit: the fraction 2/4 is the same as 1/2, but 2/4 is not reduced to the lowest terms. We can reduce any given fraction to lowest terms by finding the greatest common divisor (GCD) between the numerator and denominator, and then dividing both the numerator and denominator by the GCD.

The following is a function to find the GCD:

1 2 3 |
int gcd(int a, int b) { return (b == 0) ? (a > 0 ? a : -a) : gcd(b, a % b); } |

Add this function to your class, and write a member function named reduce() that reduces your fraction. Make sure all fractions are properly reduced.

The following should compile:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include <iostream> int main() { Fraction f1{2, 5}; f1.print(); Fraction f2{3, 8}; f2.print(); Fraction f3{ f1 * f2 }; f3.print(); Fraction f4{ f1 * 2 }; f4.print(); Fraction f5{ 2 * f2 }; f5.print(); Fraction f6{ Fraction{1, 2} * Fraction{2, 3} * Fraction{3, 4} }; f6.print(); Fraction f7{0, 6}; f7.print(); return 0; } |

And produce the result:

2/5 3/8 3/20 4/5 3/4 1/4 0/6

13.3 -- Overloading operators using normal functions |

Index |

13.1 -- Introduction to operator overloading |

Typos:

multiply the numerators together, and the denominators together.

*multiply the numerators together, then the denominators together. (", and" sounds weird for me)

multiple the numerator of

*multiply the numerator of

Good feedback. I've updated the lesson and fixed the typo. Thanks!

1b) Added overloaded multiplication operators to handle multiplication

*Add

Fixed, thanks!

Hi Alex,

In your solution to quiz 1c),

`reset()`

is called inside the constructor, before it is defined. It has not been forward declared either. How does this compile?BTW great lesson in all aspects but for some minor typos:

>

Finally implementation: ...-> you wrote`m_nCent`

instead of`m_cent`

in three places in this paragraph.>

which you will note is the minimum and maximum values that we added to cFinal.(mFinal)> In all the three quiz questions,

`iostream.h`

header is #included instead of`iostream`

.Cheers.

Unlike normal functions, member functions of a class can be declared/used in any order (the class declaration essentially serves as a prototype for all the member functions).

I've fixed all of the typos. Thanks for pointing those out!

Ah yes. Even if we define the member functions inside the class definition, they are compiled after compiling their declarations first, and then their definitions, as if they were defined out-of-line, right? I read it in the comments to a prior chapter, and forgot. Thanks for reminding! :)

I have a question that is really bothering me..

In the extra credit question of the quiz.

When writing the reduce function you use an int to hold the result of the gcd() function, and then set the m_numerator and m_denominator equal to the division between itself and our new gcd variable here.

void reduce()

{

int gcd = Fraction::gcd(m_numerator, m_denominator);

m_numerator /= gcd;

m_denominator /= gcd;

}

and this works just fine, but when I originally answered this question I did mine like this:

void reduce()

{

m_numerator /= Fraction::gcd(m_numerator, m_denominator);

m_denominator /= Fraction::gcd(m_numerator, m_denominator);

}

I did it this way to remove the need for the extra variable, and the code compiles, but it does not work. How is this different from yours as far as logic goes?

The top line in your version of reduce() modifies m_numerator, so by the time you call gcd() the second time, m_numerator has been altered. So your second call to gcd() is generating a different value than the top call because the inputs are different.

You're way better off using a temporary variable than calling a recursive function twice.

Hi Alex, I just did the same mistake. I think you should consider adding a comment in the solution code to clarify it, even though its quite obvious once you know the answer.

In quiz Question 1(c),

--------------------------------------

static int gcd(int a, int b)

{

return b == 0 ? a : gcd(b, a % b);

}

void reduce()

{

int gcd = Fraction::gcd(m_numerator, m_denominator);

------------------------------------------------------------------

1) Why function gcd is defined as Static?(any specific reason)

2) why function is called as Fraction::gcd(m_numerator, m_denominator)instead of gcd(m_numerator, m_denominator) as gcd is class member function.

3) gcd function implementation as a recursive function found to be great. In learncppp.com , similar tips for Recursive function is discussed?

Great site...

1) This gives us a convenient way to have gcd be a part of class Fraction without requiring a Fraction object to use.

2) This was done because I named the local variable gcd also. By using the Fraction:: prefix, the compiler knows I'm referring to the function, not the variable I just declared. The Fraction:: prefix would not be necessary if I gave my variable a different name.

3) I'm not sure what you're asking here. Recursive functions are discussed in lesson 7.1l.

@Alex, I am a newbie @ programming, and I was stuck at operator overloading, I was trying to understand the concepts through one of the well known authors' book! but couldn't figure out exactly what's going on. Now I have understood the same, after I went through your explanations and code snippets multiple times! :).

Thanks a ton for elaborating it in this way.

I got a few doubts though, they are as follows:

1) I noticed that, you have passed objects by references, I am aware of the implementation of references, but I could not understand why are the objects passed by references in these code examples( eg Cents program). I passed them by value and I am getting the correct answer.

Any specific reason as to why you have passed the objects by references ? (I have read that its expensive to copy objects). Request you to please clarify my doubt.

2) How can operator overloading be achieved if I have two different classes and I want to pass an object of another class to the first class?

Thanks!

1) Passing objects by (const) reference avoids making a potentially expensive copy. That's usually why it's done.

2) I'm not sure I understand what you're trying to do. Can you give me some more detail?

Thanks for your clarification for point 1).

2) Let us assume I have two different classes, with two different objects respectively. I want to perform operator overloading on these two different class objects. Hope I have made it clear.

Thanks!

I'm presuming you mean something like this:

If so, you can make the overloaded operator a friend of both class A and B so it has access to the internals of both class objects.

Okay I get you. I will do it accordingly! Thanks again for your inputs :)

Alex, in quiz '1c', pls make a slight correction with respect to mathematics terminology. "greatest common denominator (GCD)" should be "greatest common divisor (GCD)".

Updated! Thanks for letting me know. I apologize to all of the mathematics people I offended with my callous disregard for mathematical terminology. ;)

Lol! :p you've more than compensated for by your immense efforts in generously sharing your C++ knowledge with all! Thank you so much for your impressive contribution Alex! :)

Hi Alex,

Great lesson! In the solution to 1c, wouldn't it make sense for gcd() to be a private static member function, since only reduce() is making use of it? Also reduce() would also make sense to be private if we are only calling it in the constructor. Nothing outside of the class should have a reason for calling reduce() if our fractions are automatically reduced upon instantiation.

Your call whether to make it private or public. Personally, I try not to assume which things people will find useful. Since there's no harm in leaving it public, I left it public.

Hi, Thanks for this lovely tutorial. I've learn a lot by reading it. :)

I just want to mention I found this might be a typo in your content.

Is this suppose to be operator-

Thanks! Fixed.

What happen if don't use friend function here ?

Is there any other way to do the same ?

[class Cents

{

private:

int m_nCents;

public:

Cents(int nCents) { m_nCents = nCents; }

// Add Cents + Cents

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

int GetCents() { return m_nCents; }

};

// note: this function is not a member function!

Cents operator+(const Cents &c1, const Cents &c2)

{

// use the Cents constructor and operator+(int, int)

return Cents(c1.m_nCents + c2.m_nCents);

}

int main()

{

Cents cCents1(6);

Cents cCents2(8);

Cents cCentsSum = cCents1 + cCents2;

std::cout << "I have " << cCentsSum .GetCents() << " cents." << std::endl;

return 0;

}

]

Sure, there are often multiple ways to solve the same problem in C++. operator+ could be written as a non-friend member function as follows:

(I'm doing this one from memory so there may be an error somewhere)

Hi!

Can you explain me is it better to use

, or

?

Thanks in advance!

Both will work, so it's really a matter of which you prefer. Personally, I find it more intuitive to use the friend function version, since operator+ does not modify the left-hand parameter.

I'm trying to figure out why you define the operator+ as:

rather than

I get the same result.Why is the class type prepended to it as if it was a function? Pardon me if it's been discussed in a previous section, I just remember seeing anything like that.

In the one I wrote, I'm explicitly defining the return value as a Cents object, calling the Cents constructor and passing it an integer parameter.

In the one you wrote, you're relying on the compiler to realize that the return value is a Cents and we're returning an int, and therefore it should go see if there's an Cents constructor that takes an int parameter so it can do an implicit conversion.

Both work, but the top is better stylistically because it makes what's happening explicit.

The object we're returning in one I wrote is an anonymous Cents object. Anonymous objects are covered at the end of chapter 8.

I don't understand this line and how you get 16 :(

MinMax cMFinal = cM1 + cM2 + 5 + 8 + cM3 + 16;

could you include more steps for explanations..?

All the MinMax class does is keep track of the smallest and largest number it's seen so far.

So these lines:

operator+ has higher precedence than operator=, so we start adding from left to right. cM1 + cM2 is (10, 15) + (8, 11), which equals (8, 15). Then we add 5 (which is (5, 5)), which equals (5, 15). Then we add 8, which does nothing. Then we add cM3 (which is (3, 12)), which yields (3, 15). Finally, we add 16 (which is (16, 16)), which yields (3, 16).

So our final answer is (3, 16).

so simple, thanks :)

In the last example minMax, we are not doing any arithmetic addition, instead we are keeping track of minimum and maximum values seen so far. In this case we overloaded + operator to keep track of minimum and maximum values of Objects.

This means we can overload operators to do any task not just only arithmetic operation. Am i correct?

Yes. If you want to change the meaning of an operator for your specific class, you can (though it's generally not recommended unless the updated meaning is fairly natural). Just keep in mind that you can not change the operator's precedence.

Hi Alex

Thank you for this great tutorials ^_^

just a question about the last paragraph

One other interesting thing to note is that we defined operator+(int, MinMax) by calling operator+(MinMax, int). This is slightly less efficient than implementing it directly (due to the extra function call)

if we use inline for this function

inline MinMax operator+(const MinMax &cM, int nValue);

is our program efficient like implementing it directly ?

sorry about my English

It depends on whether the compiler honors the inline request or not. It may or may not.

I dont get this lesson ?!

- Why do you use Cents as a type when you declare operator+

_ Can you show me how does operator+ works in main in the first example

Thank you so much Alex!

We're declaring an overloaded operator+ that takes two Cents objects and returns a Cents object that represents the sum.

So when we do this:

The compiler evaluates cCents1 + cCents2, and looks for an overloaded operator+ function to add them (which it finds, because we wrote it). The function returns a temporary Cents value, that's copied back into cCentsSum.

I now get it Alex, thank you!

1 more struggle: how can you do this: Cents c1 = Cents(4) + 6;

Shouldnt it be like : Cents test ( 4 );

Cents c1 = test +6; ?

Great question!

C++ compilers are smart. When the compiler sees something like this:

First it looks to see if there's an overloaded operator+ that takes a Cents and an int parameter. In this case, there isn't. But it does see that there's an overloaded operator+ that takes a Cents and a Cents parameter. So the next question it asks is whether the int can be implicitly converted into a Cents. Because we've provided a constructor that takes an int, the answer is yes! So, the 6 gets converted into Cents(6), and the overloaded operator+ that adds two Cents gets called.

Pretty clever if you ask me.

Alex, in my program

This line works, even if operator+ is not defined for these type of parameters and constructor is NOT declared as 'explicit'.

But, below line gives and error

Here the implicit conversion of 10 to Cents(10) is not taking place when operator+ is not defined and presence of explicit keyword to constructor doesn't matter.

Please throw some light on this.

I'm not sure why this would work. I tried this on Visual Studio 2015 and neither line compiled.

As defined, there's no conversion between a Cents and an int (since we haven't overloaded the int typecast), so I'm not sure how it would know how to convert c2 into an int to add it.

It was a const keyword in operator+ that takes a Cents and a Cents as parameter. Have a look.

I think what may be happening here is that the compiler is noting that there's a function that can add two Cents, so it looks to see if an integer can be converted into a Cents object. It can, since there's a Cents(int) constructor. Thus, the compiler creates an anonymous Cents object from the integer and passes it to operator+.

However, this only works if the operator+ has const parameters, since you can't have a non-const reference to a temporary/anonymous object. Similarly, if the function is marked as explicit, the compiler won't do the conversion from int to Cents.

#include <iostream>

#include<string>

using namespace std;

class Calc

{

private:

int mval;

public:

Calc(int a){mval=a;

}

friend Calc operator+(Calc &a,int &b);

friend Calc operator+(int &a,Calc &b);

int geta(){return mval;

}

};

Calc operator+(Calc &a,int &b){

return Calc(a.mval+b);

}

Calc operator+(int &a,Calc &b){

return Calc(a+b.mval);

}

main(){

Calc a = Calc(2)+5;

cout<<a.geta();

}

what is wrong with it?

Your function

should be one of these:

It's failing because you're trying to add the literal 5, and you can't pass a literal to a non-const reference. Your int parameter either needs to be pass by value or pass by const reference in order to accommodate literals.

"Because you probably already have a constructor that does this, you may be tempted to try to call the constructor from your member function. As mentioned, chaining constructor calls are illegal in C++"

Extracted from "Constructors part II". If it is illegal, why you called the constructor from a friend function which is almost a member function???

Isn't it illegal????? Or MinMax is only written for making sure that the evaluated value would be a MinMax?

In older versions of C++, a constructor cannot call another constructor (this restriction was lifted in C++11).

This isn't directly calling a constructor: it's explicitly creating an anonymous object of type MinMax (which will indirectly call a constructor).

What we're doing here is essentially the same as:

Just without the temporary variable.

Hello,

In my "practice code" I have created a relatively simple "Words" class meant to take in some strings.

In it I have tried to overload the + operator (and made it a friend function) in order to join strings as follows:

wherein two strings would be concatenated.

This works for assignments such as:

This absolutely refuses to work for:

At first I thought it was due to (cWord1+cWord2) resolving to an anonymous variable, but I don't think that is the reason.

Is there something fundamental that I am misunderstanding?

Thank you very much for the information on the website in general - extremely useful.

Adam

Making your operator+ function call parameters const. This avoids problems with trying to create references to temporary objects.

how does MinMaxs constructor evaluate this expression and put 3 into min member and 16 into max member

MinMax cMFinal = cM1 + cM2 + 5 + 8 + cM3 + 16;

did i miss something about anonymous class objects?? can someone please someone could step by step this evaluation

I've updated the lesson to answer this question more thoroughly, since it's not necessarily obvious.

In this example...

#include

using namespace std;

class Cents

{

private:

int m_nCents;

public:

Cents(int nCents) { m_nCents = nCents; }

// Overload cCents + int

friend Cents operator+(const Cents &cCents, int nCents);

// Overload int + cCents

friend Cents operator+(int nCents, const Cents &cCents);

int GetCents() { return m_nCents; }

};

// note: this function is not a member function!

Cents operator+(const Cents &cCents, int nCents)

{

return Cents(cCents.m_nCents + nCents);

}

// note: this function is not a member function!

Cents operator+(int nCents, const Cents &cCents)

{

return Cents(cCents.m_nCents + nCents);

}

int main()

{

Cents c1 = Cents(4) + 6;

Cents c2 = 6 + Cents(4);

std::cout << "I have " << c1.GetCents() << " cents." << std::endl;

std::cout << "I have " << c2.GetCents() << " cents." << std::endl;

return 0;

}

...it's not clear to me how the expression Cents(4)+6 is evaluated. Yeah I know that we're overloading operator "+" for operands of types Cents and int respectively.

As I understand Censt(4) is the constructor, right? So when...

Cents operator+(const Cents &cCents, int nCents)

{

return Cents(cCents.m_nCents + nCents);

}

...is called does cCenst become a reference to Cents(4)?

From the line...

return Cents(cCents.m_nCents + nCents);

...one can deduce that cCenst is an object of type Censt since we access m_nCents via member selection operator "." But Censt(4) is a constructor and not a class object.

To me it doesn't make sense for cCenst to be a reference to Cents(4) since they're not equivalent.

Cents(4) is a constructor that constructs a Cents object, and then operator+(Cents, int) is called to evaluate operands Cents(4) and 6. So yes, in this case, &cCents becomes a reference to the object constructed by Cents(4).

thank you very much sir.....

this site is very helpful to me.

Hi Alex,

Thanks a lot for the tutorials...:)

having a doubt-

in the code below if i just remove the keyword friend from the operator function i am getting compilation error :operator+ must take either 0 or 1 argument...why??though we have declared it with two argument...

#include

#include

class Cents

{

private:

int m_nCents;

public:

Cents(int nCents) { m_nCents = nCents; }

// Add Cents + Cents

Cents operator+(const Cents &c1, const Cents &c2); /*I have removed friend from here*/

int GetCents() { return m_nCents; }

};

// note: this function is not a member function!

Cents::Cents operator+(const Cents &c1, const Cents &c2)

{

// use the Cents constructor and operator+(int, int)

return Cents(c1.m_nCents + c2.m_nCents);

}

int main()

{

Cents cCents1(6);

Cents cCents2(8);

Cents cCentsSum = 4+3+cCents1 + cCents2+5;

std::cout << "I have " << cCentsSum .GetCents() << " cents." << std::endl;

getch();

return 0;

}

By making the function a member function, the function that you have declared has 3 arguments: Cents* const this, const Cents &c1, and const Cents &c2. Since operator+ is a binary operator, it must have 2 parameters.

An updated version that Works On My Machine (TM):

Hey Alex,

Thanks for the tutorials.... I have a question though about the following code. This code compiles properly but i'm wondering why the compiler did not issue an error message when cent2.m_nCents was accessed in the overloaded member function operator+ of myCent1 in main, if the member was private. :

class Cents

{

private:

m_nCents;

public:

//Constructor

Cents( int nCents ) { m_nCents = nCents; }

int GetCents(){ return m_nCents; }

Cents operator+( const Cents& cent2 )

{

return Cents( this->m_nCents + cent2.m_nCents );

}

};

int main()

{

using namespace std;

Cents myCent1(6);

Cents myCent2(8);

Cents myCent3( myCent1 + myCent2 );

cout << myCent3.GetCents() << endl;

return EXIT_SUCCESS;

}

btw, i learned this in some OOP book...

I would imagine become that private variable is accessed through a public member function, which is perfectly legal.

This. Your operator+ is a member function, so it is able to access private class members directly.

Why do you use a reference as a parameter:

it works the same when I use this:

I also changed the declaration of the friend functionGot confused too, hope Alex could answer this.

The advantage is covered in the section on passing by reference.

Here's a recap: Your modified declaration passes the MinMax instances by value, which requires creating additional copies in memory. For larger classes, this can cause a large amount of overhead and risk a stack overflow. It is a good general rule to pass user-defined objects by reference as a way to avoid these risks.

This. Non-fundamental data types should be passed by const reference to avoid making a temporary copy. This is done mainly for performance reasons.

Hi Alex,

I am really confused with this operator overloading concept. Especially I dont understand y shoul

d we use a friend class. In the example discussed above

// note: this function is not a member function!

Cents operator+(Cents &c1, Cents &c2)

{

// use the Cents constructor and operator+(int, int)

return Cents(c1.m_nCents + c2.m_nCents);

}

A.Y r we using call by reference??

B.What happens in Main when

Cents cCentsSum = cCents1 + cCents2;

is encountered/

A lot of times we use friend classes when doing operator overloading because it makes the functions easier to write.

Remember that a member function always has to have an implicit data type that is pointed to by *this. Thus, if you do something like this:

, the compiler translates that to a.add(b). a becomes the implicit data type. Now we have a as an implicit type, and b as an explicit type. This can be awkward.

However, if we use a friend function, then both a and b come through as parameters, which makes the functions easier to write because we don't have to worry about any implicit variables.

In this case, we use call by reference because we don't want to copy the Cents class to do a pass-by-value. Really, those should be const references.

Hi Alex, Is it still good coding if we just have the operators as member functions, I've only started and it appears easier for me to have everything inside the class.

Also in light of using friend functions and manageability where do you recommend I keep them (the friend functions). Just below my class, like your example, or somewhere else?

Cheers,

Yes, it's fine if you prefer the member function variants. Friend vs member function is mostly a matter of style, except for a few cases.

For the friend functions, I usually put them either below the class (if the class is declared in a .cpp file), or in the corresponding .cpp file (if the class is declared in a .h file).

You might want to explain why the operators should be a friend function instead of a member function and therefore breaking encapsulation.

I'll cover this once I've covered how to do overloaded operators via the member function method.

Hi

I have an observation. Instead of having many versions of overloading the operators with different combos it should be sufficient to have one version of operator to do Objects & use type conversion to handle other types. Otherwise the no. of combos of operators may become too unwieldy.

Thus, the Cents & MinMax examples work with minimal operator versions as below.

This is true, and is a great observation. The one major downside of doing it this way is that it is about half as efficient since you have to do the extra step of converting to a temporary object before producing your final result. Whether efficiency or additional maintainability is a larger concern depends on the nature of the class and project. Never-the-less, thanks for the great point.

Hi all,

Note that the code above does not work when the programmer use template class instead (cf. http://www.learncpp.com/cpp-tutorial/143-template-classes for deatils):

This code makes the g++ compiler complaining about operator+ :

The programmer shall explicitly define the operator+ (as Alex has done in its example).

The Jayaram suggestion is nice, but it implies some magics from compiler.

The advantage that I see from the Alex code sample is that there is no magic, making code clearer and allow the programmer changing a non template class into template class without surprise :)

I don't understand how your code works with respect to the addition at the end. To me it looks like that single parameter Minmax would handle the ints so it would treat them like a class where both the min and the max were the same value. I never see a function call to that though so how does your program know how to treat the addition (no pun intended) of intends along with that of classes?

He's relying on the compiler to do an implicit conversion from int to a Cents object using the Cents(int) constructor. I don't like implicit conversions (they lead to unexpected behavior), so I try to avoid them in favor of being explicit.

Hi alex, I have a dobout when you call

you actually create a Cents object in the "cCents1 + cCents2" part and then it is copied to cCentsSum, however in the case that you allocate a dinamic variable whit

new, when you call the "cCents1 + cCents2" part, the object will never go out of scope, and you will have a memory leak, I am right?Another thing, when you do the

part, its the = operator always overloaded to copy every member variable of a class?

Tnx, -Kin-

Yes, objects declared with new have to be deleted, otherwise the memory is lost and you have a memory leak. In this case, since we aren't using new, that isn't an issue we have to worry about.

The compiler supplies every class with a default implementation of operator=, which copies each member variable.

Sooo.... What do you do when you DO use 'new'? Been wrestling with this for weeks because I'm making my own String class.

Say I have this command "str1 = str2 + str3"

If you change your op + to return, say, a String by reference (String&) and return an unnamed object, then the object ends up getting destroyed before the op = fires. If you don't return by reference, then you end up with a nice fat memory leak.

How the heck to do you work around that? Add an extra parameter to your op = to know whether or not it was called after an op + so that it can delete the temp string?

It wouldn't make sense for an overloaded operator+ to return anything by reference, because as you note, the referenced object will probably get destroyed before the assignment takes place. operator+ should return by value (in this case, an anonymous String).

Hello Alex -

A. Two typos:

1. "When the operator does not modify

itsoperands"2. "Finally, implementation: to add

twoCents objects together"B. If instead of:

we had:

that would break the logic of the code (it would still return 3,16 instead of 2,25). How would you handle it? Like this maybe?:

Thanks for the edits. As for point B, that's actually an interesting concern. If possible, it's always a good idea to think about how the user might misuse a class -- and if there's a reasonable way to handle it, then do so. In this case, your suggestion is perfect -- if the user passes in the min and max in the wrong order to the constructor, we can detect that and flip them.