Yesterday I talked about what are user-defined conversions and how Single Argument constructor and overloaded type conversions operators act as type conversions from a Class (user-defined type) to any other type and vica-versa.
Today’s questions is more like a design question, C++ provide us the functionality to define user-defined type conversions, but should is it a good design to define such type conversions in our class?
Let us take the class declaration from yesterday’s example:
class Rational { private: int numerator, denomenator; public: /* This constructor will act as all * default constructor, Single argument constructor * and 2-argument constructor, because of default arguments. */ Rational(int num=0, den=1):numerator(num), denomenator(den){} // implicit type convertor from Rationals to double. operator double() const; };
These convertors comes handy when we want intentional conversions to happen as below:
void demoFun1(double); void demoFun2(Rational); Rational r(1,2); double d = 4.5; demoFun1(r); //OK. will call type convertor function to convert from Rational to double implicit . demoFun2(d); //OK. will call the single argument constructor to convert from double to Rational.
Ok, so these are examples to show the usage, but more often than not they are also the side effects. What if the user is not intending to call the function which is getting called. remember the call
demoFun2(d);
does not make it clear that it is calling function with Rational argument and not double. If someone is just reading the code then he may get confused.
So, the suggestion is to either make the call explicit by declaring the single argument constructor explicit as below
Rational(int num=0, den=1):numerator(num), denomenator(den) explicit {}
But this can only be applied to single argument constructors, We cannot declare implicit type conversion operators explicit. So it is better to avoid them al together.
Remember, if you want to convert a string class object to a c-style array (of pointers), then you will have to call function c_str() defined in string class.
The makers of string class could have opted to define an implicit type conversion operator to convert a string object to char*, but they choose, not to, and went ahead with defining a separate function which performs exactly the same (convert a string to char*).
Those, were intelligent people. Are you?