User-defined type conversions in C++ (Single argument constructor & implicit type conversion operators function)
June 13, 2012
N Doors Puzzle
June 13, 2012

Should we use user-defined type conversions

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?

Solution:

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?

Leave a Reply

Your email address will not be published. Required fields are marked *