As we can invoke the explicit cast operator, using static_cast, a C-style cast, or a constructor style cast. I am confusing how exactly the operator interpret to these three casts.
For example, consider the following code. The const Money& balance
in display_balance()
can be cast to double in three ways. So what are these cast interpret. What I thought is there is only one explicit cast operator in Money, so the calling may would be balance.operator ()
. I really can't figure out how does the three different casting be interpreted.
class Money
{
public:
Money() : amount{ 0.0 } {};
Money(double _amount) : amount{ _amount } {};
explicit operator double() const { return amount; }
private:
double amount;
};
void display_balance(const Money& balance)
{
std::cout << "The balance is: " << (double)balance << "\n";
std::cout << "The balance is: " << double(balance) << "\n";
std::cout << "The balance is: " << static_cast<double>(balance) << "\n";
}
Type Casting
It isn't the syntax you use when casting that determines how that cast is performed, it's the context based on the variable types.
When the compiler sees that you're trying to cast from
Money
todouble
, it tries to figure out a way to accomplish that - in every case, it uses theMoney::operator double()
operator because in every casedouble
was specified as the target type.C++ almost always allows you to accomplish one task in multiple different ways due to historical reasons; even its name alludes to its original goal: extending the C language.
Consider the following syntaxes:
Once this is compiled, there isn't really any difference in which syntax you used; all of them call
Money::operator double()
.Of course, casting is always subject to operator precedence.
Note: While in this case all of the approaches are the same, this is not true in all cases.
Whenever possible, use
static_cast
instead of c-style or functional casts - you can read more about why here.Explicit vs. Implicit Type Casting
Consider the following objects:
Money
is your class.Cash
is a copy ofMoney
that allows implicit casting.Now consider the following function that accepts a
double
:In order to
BuySomething()
withMoney
, we must explicitly cast it todouble
first:However, we can
BuySomething()
withCash
without explicitly casting it first:This is because when the compiler sees
BuySomething(cash);
, it knows thatBuySomething()
doesn't acceptCash
- it acceptsdouble
- so rather than just throwing an error, it tries to figure out a way to convertCash
todouble
, and in the process finds our conversion operator.If you notice something wrong with my explaination, let me know in the comments.