8.4 Type Conversion Operators
Type conversion is needed to resolve mismatched types in assignments and expressions, or when passing parameters. The existence of type conversions makes it possible to use one type when a different type may be expected, the type conversion bridging the difference between them.
Type conversions may be either implicit or explicit, as shown in the following examples using built in types:
int i; float f; f = i; // implicit conversion f = (float)i; // explicit conversion f = float(i); // explicit conversion
With implicit type conversion, the compiler is given the responsibility to determine when a conversion is required and how to perform the conversion. With explicit type conversion, the programmer assumes this responsibility. Notice that there are two different, but equivalent, syntaxes for explicit conversion.
Type conversions involving user-defined classes are also meaningful. The following examples illustrate conversion between a user defined class and a built-in type and conversion between two user defined types.
The first example, illustrating type converstion between a user-defined class and a built-in type, uses the class Counter introduced in chapter 6, on inheritance. Objects of this class can be incremented by a Next operation and displayed in the user interface by associating the Counter with a TextBox. The internal integer value of a Counter can be extracted by the Value method so that a Counter object can be used in contexts where an integer values is expected:
Counter count(0); // manipulate count if ( count.Value() > 0) ... if ( count.Value() == 100) ... cout << count.Value();
This syntax, however, is awkward and unnatural.
Because a Counter object can be viewed as an integer value that has added capabilities (i.e., the ability to be displayed in the user interface), it is sensible to expect that a Counter object could be used in the following, more direct, ways:
Counter count(0); // manipulate count if ( count > 0) ... if ( count == 100) ... cout << count;
In this code, the expectation is that a Counter object can be treated as a simple integer. One way to achieve this effect is to add to the Counter class overloaded operators for such functions as comparisons, arithmetic, and/or stream I/O. A simpler alternative is to use type conversion.
A type-conversion operator is added to the user defined Counter class as in the figure below, where the operator overloading defines a type-conversion operator that can be used to produce an int type from a Counter object. This operator will be used whenever an implicit or explict conversion of a Counter object to an int is required.
Notice that constructors also play a role in type conversion. The constructor for a Counter object is defined in the Counter class as shown below. This constructor can be viewed as a way of converting an int value to a Counter object. In general, a class's constructor that takes a single argument of a type other than that class itself serves as a type converted from the argument type to the class.