This is exactly this algorithm applied
in the version you can see here. There is one subtlety,
related to this passage by value here.
Indeed, we are using this header for "operator+",
which is the recommended header since C++ 2011.
Thus, when we write something like "c1 + c2"
(thus calling this operator " + " )
what will happen is that the value of the "Complexe" c1 will be copied into z1.
z1 is an area local to the function "operator+"
on which we can work and which will be finally returned.
We thus realize that
z1 plays exactly the role of "tmp".
Therefore, it is pointless to redefine, in the body of "operator+",
another intermediate variable
in which we could copy the first operand here.
This role is already fulfilled by the parameter passed by value here.
In other words, the copy of the first operand c1,
done in an intermediate variable "tmp"
is realized de facto upon this by-value call here.
Naturally, the algorithm described here is placed inside a function.
Once the computation is complete, the value will be returned;
this is precisely done here.
We thus get a definition of the operator " + "
done through " += ". This definition is very concise, elegant
and mostly establishes a semantic link
between the operator " += " and the operator " + ".
These two operators should not be defined separately.
Please note that this way to define the header using a passage by value
lets the modern compiler C++ 2011 to process many an optimization.
By the way, this new version of the operator " + ",
defined through " += ",
has the edge of sparing us the trouble of using getters
which were necessary for the external function
to access the private attributes of "Complexe".
These getters are not necessary anymore which is good for the encapsulation.
We know that getters running rampant
can nefarious to the encapsulation.
Thus, we can use outer overloading or inner overloading for operators.
In certain cases though, we do not have a choice as to how to proceed.
For example,
for the printing operator we have seen in the previous episode,
we can only overload it with a (non-member) function.
In some other cases, we may choose between the two.
For example, regarding the operator " + ", which we have encountered already,
it is perfectly possible to define it through an inner overloading,
like this.
It is also possible to define it through an outer overloading;
we have done just that in the previous examples.
Be careful though,
we have seen that, during the external definition of an operator,
we could be tempted to use the "friend".
In the previous examples,
we have always avoided to do so.
Some people could be tempted to do it nonetheless;
it is a very poor idea, breaking the encapsulation
and not a good way to proceed.
This leads us to a few recommendations regarding methodology.
This concerns the choice between inner overloading
and outer overloading for a given operator.
First recommendation :
it is usually recommended to prefer the outer overloading
every time we can do so without having to resort to the "friend" keyword
in the body of the function.
This means, every time we can write the operator
through the member functions of the classe's interface without useless copies.
This was the case with the operator " + " which we could define
without resorting to the "friend" keyword.
In this case, it is thus recommended to define this operator
through an outer overloading, with a function.
On the other hand, if the operator is close to the class,
as was the case before with the operator " += ",
which required the instance to be modified
and thus internal access,
and possibly supplementary useless copies.
Then, in this case,
it is much better to use inner overloading.
You now know all the basics
on operator overloading. In the last episode,
we will discuss the sharper aspects
and will bring the light on a few points,
left in the dark until now.