Conversion Functions

In conversion by constructors, described in the previous section, objects of one type can be implicitly converted to a particular class type. This section describes a means by which you can provide explicit conversions from a given class type to another type. Conversion from a class type is often accomplished using conversion functions. Conversion functions use the following syntax:

Syntax

conversion-function-name :

operator conversion-type-name ()

conversion-type-name :

type-specifier-list ptr-operatoropt

The following example specifies a conversion function that converts type Money to type double:

class Money
{
public:
    Money();
    operator double() { return _amount; }
private:
    double _amount;
};

Given the preceding class declaration, the following code can be written:

Money Account;
...
double CashOnHand = Account;

The initialization of CashOnHand with Account causes a conversion from type Account to type double.

Conversion functions are often called “cast operators” because they (along with constructors) are the functions called when a cast is used. The following example uses a cast, or explicit conversion, to print the current value of an object of type Money:

cout << (double)Account << endl;

Conversion functions are inherited in derived classes. Conversion operators hide only base-class conversion operators that convert to exactly the same type. Therefore, a user-defined operator int function does not hide a user-defined operator short function in a base class.

Only one user-defined conversion function is applied when performing implicit conversions. If there is no explicitly defined conversion function, the compiler does not look for intermediate types into which an object can be converted.

If a conversion is required that causes an ambiguity, an error is generated. Ambiguities arise when more than one user-defined conversion is available or when a user-defined conversion and a built-in conversion exist.

The following example illustrates a class declaration with a potential ambiguity:

#include <string.h>

class String
{
public:
    // Define constructor that converts from type char *.
    String( char *s ) { strcpy( _text, s ); }
    // Define conversion to type char *.
    operator char *() { return _text; }
    int operator==( const String &s ) 
    { return !strcmp( _text, s._text ); }
private:
    char _text[80];
};

int main()
{
    String s( "abcd" );
    char  *ch = "efgh";

    // Cause the compiler to select a conversion.
    return s == ch;
}

In the expression s == ch, the compiler has two choices and no way of determining which is correct. It can convert ch to an object of type String using the constructor and then perform the comparison using the user-defined operator==. Or it can convert s to a pointer of type char * using the conversion function and then perform a comparison of the pointers.

Because neither choice is “more correct” than the other, the compiler cannot determine the meaning of the comparison expression, and it generates an error.