"a*b is an r-value, and hence have no location in memory" it is not quite right.
I add prints. The comments are the prints for each line of code
#include <iostream>
using namespace std;
struct Rational {
Rational(int numer, int denom) : numer(numer), denom(denom) {
cout << "object init with parameters\n";
}
Rational(const Rational& r)
{
this->denom = r.denom;
this->numer = r.numer;
cout << "object init with Rational\n";
}
~Rational() {
cout << "object destroy\n";
}
int numer, denom;
};
Rational operator*(const Rational& lhs, const Rational& rhs) {
cout << "operator*\n";
return Rational(lhs.numer * rhs.numer, lhs.denom * rhs.denom);
}
int main() {
Rational a(1, 2), b(3, 4), c(5, 6); // 3x object init with parameters
cout << "after a, b, c\n"; // after a, b, c
Rational d = a * b = c; // operator*, object init with parameters, object init with Rational, object destroy
cout << "end\n"; // end
// 4x object destroy
}
In the line Rational d = a * b = c; d is equal to c. This line call operator* function, that call the object init with parameters constructor. After that c object is copied to d object by calling copy constructor.
If you write the line: Rational d = a = c; // d == c // print only: object init with Rational the compiler assign the d object only to the last assign (object c)