It is usually a bad idea to make class support implicit type conversion. Of course, this rule has exceptions when creating a value type. Assume that a class is used to represent rational numbers, and an integer is allowed.
Implicit conversion to rational numbers seems reasonable.
Class rational {
Public:
Rational (INT Numerator = 0, int Denominator = 1); // deliberately not explicit; allows int-to-rational implicit conversion
Int numerator () const;
Int denominator () const;
};
When Arithmetic Operators are supported, consider whether to implement the member function or non-member function:
Let's first look at the writing of member functions:
Class rational {
Public:
Const rational operator * (const rational & RHs) const;
};
Rational oneeight (1, 8 );
Rational onehalf (1, 2 );
Rational result = onehalf * oneeight; // nice
Result = Result * oneeight; // OK
However, you want to support mixed operations:
Result = onehalf * 2; // OK 2 is implicitly converted.
Result = 2 * onehalf; // wrong!
In this way, you can see at a glance:
Result = onehalf. Operator * (2); // OK
Result = 2. Operator * (onehalf); // wrong!
Onehalf is an object of A Class containing operator * functions. 2. If no corresponding class exists, the compiler will try to find the non-member operator * (that is, within the namespace or global scope) that can be called as follows ):
Result = Operator * (2, onehalf); // wrong!
In this example, the non-member operator * that accepts int and rational parameters does not exist. Therefore, the search fails.
This parameter is a qualified participant in implicit type conversion only when the parameter is listed in the parameter list. The position is equivalent to the metaphor parameter of "the object to which the called member function belongs" -- that is, this object -- and is never a qualified participant in implicit conversion.
To support mixed operations. Turning operator * into a non-member function allows the compiler to perform implicit type conversion on each real parameter:
Const rational operator * (const rational & LHS, const rational & RHs)
{
Return rational (LHS. numerator () * RHS. numerator (), LHS. denominator () * RHS. denominator ());
}
Result = 2 * onehalf; // OK! The compilation is successful!
Does operator * need to be a rational friend function? The answer is no, because operator * is completely completed by the rational public interface, and should be avoided whenever you can avoid the friend function.
When rational becomes a class template, there are some new controversies, solutions, and condentions which form clause 46.