One way to avoid unnecessary object construction is to use a reference instead of an object to store the unnamed temporary object returned by value
This tip references both Scott Meyers' Effective C++ Item 23 ("Don't try to return a reference when you must return an object.") and Item 20 ("Facilitate the return value optimization.").
Here's the code:
const Rational& operator*(const Rational& lhs, const Rational& rhs)
return Rational(lhs.n * rhs.n, lhs.d * rhs.d);
Rational a(1, 2);
Rational b(3, 5);
Rational c = a*b; // This incurs an additional object construction.
[const] Rational& c = a*b;
// A better way of doing it. Here we just give the returned temporary object a name 'c'.