13.11 — Overloading typecasts

In lesson 8.5 -- Explicit type conversion (casting) and static_cast, you learned that C++ allows you to convert one data type to another. The following example shows an int being converted into a double:

C++ already knows how to convert between the built-in data types. However, it does not know how to convert any of our user-defined classes. That’s where overloading the typecast operators comes into play.

User-defined conversions allow us to convert our class into another data type. Take a look at the following class:

This class is pretty simple: it holds some number of cents as an integer, and provides access functions to get and set the number of cents. It also provides a constructor for converting an int into a Cents.

If we can convert an int into a Cents, then doesn’t it also make sense for us to be able to convert a Cents back into an int? In some cases, this might not be true, but in this case, it does make sense.

In the following example, we have to use getCents() to convert our Cents variable back into an integer so we can print it using printInt():

If we have already written a lot of functions that take integers as parameters, our code will be littered with calls to getCents(), which makes it more messy than it needs to be.

To make things easier, we can provide a user-defined conversion by overloading the int typecast. This will allow us to cast our Cents class directly into an int. The following example shows how this is done:

There are three things to note:

  1. To overload the function that casts our class to an int, we write a new function in our class called operator int(). Note that there is a space between the word operator and the type we are casting to.
  2. User-defined conversions do not take parameters, as there is no way to pass arguments to them.
  3. User-defined conversions do not have a return type. C++ assumes you will be returning the correct type.

Now in our example, we can call printInt() like this:

The compiler will first note that function printInt takes an integer parameter. Then it will note that variable cents is not an int. Finally, it will look to see if we’ve provided a way to convert a Cents into an int. Since we have, it will call our operator int() function, which returns an int, and the returned int will be passed to printInt().

We can now also explicitly cast our Cents variable to an int:

You can provide user-defined conversions for any data type you wish, including your own user-defined data types!

Here’s a new class called Dollars that provides an overloaded Cents conversion:

This allows us to convert a Dollars object directly into a Cents object! This allows you to do something like this:

Consequently, this program will print the value:


which makes sense, since 9 dollars is 900 cents!

13.12 -- The copy constructor
13.10 -- Overloading the parenthesis operator

102 comments to 13.11 — Overloading typecasts

  • darlanfa

    Here's is my solution to the problem of overloading the conversions both ways

    • pedamase

      Request to check if this works with static cast, just modified the code of main function alone trying to convert cents to dollars. could see compilation error "error: call of overloaded ‘Dollars(Cents&)’ is ambiguous "

  • Andreas Krug

    Small suggestion: In the lesson 6.15 -- Implicit type conversion (coercion)  instead of  In the lesson 4.4 -- Type conversion and casting

  • Aphamino


    I seem to have the same problem as many others. I tried the program to convert from Cents to Dollars but no matter what I do it just doesn't work and I'm out of options. I tried creating different kind of header files which I #included in my main cpp-file but to no avail. Even google search doesn't help. How on earth is it done? My main looked like this:

    As you can probably notice, I also tried changing the type of dollars to 'double' so that it wouldn't lose the decimals when converting cents to dollars. I get so disheartened when I can't get this kind of simple program to work after days of trying. :(

  • yeokaiwei

    1. Feedback
    //1. Still can't solve how to convert both ways from Dollars to Cents and vice versa.
    It is not as intuitive as copying the code from Cents and pasting it into Dollars.

  • yeokaiwei

    I tried modifying the code to do the opposite and convert cents in dollars.

    It doesn't seem to work.

    May I ask why?

    I get C2833, operator is not a recognised type

  • yeokaiwei

    1. Query about operator clash
    How do you know if an operator is overloaded?

    If there are multiple classes each overloading an operator, how would it resolve?

    class A
    int operator()(int value)
      return something;


    class B
    int operator()(int value)
      return somethingdifferent;

    Does it not matter because the operator() is specific to its own Class?

    • Sam

      It operates on the objects implicit this pointer (as explained previously).

      Here is some example code:

      You can even try replacing the calls to a(5) and b(10) to what the compiler converts them to, and you'll notice that they work as well. Hopefully this answers your question.

  • Zuhail

    Hey , in your last example of converting Dollar instance to Cents , I actually tried to add a typecast operator in Cents class to convert it into Dollar but I got error
    So I declared the Dollar class by following:
    class Dollar ; and then the rest of the code , but still compiler said that Dollar class is not complete even though I've added every necessary thing into Dollar class.

    Is it not possible just to add typecast operator in both Cents and Dollar for each other?

    • Zuhail

      Here's the code

      • nascardriver

        Your compiler doesn't know enough about `Dollars` in line 16 to use it.
        You can add a converting constructor to `Dollars` from `Cents` instead

  • srt1104

    What exactly happens when you do



    Also in the general sense of a function prototype, user-defined conversions do not have a return type but the function identifier itself is a type-name so doesn't it check with it that what we are returning from the function is atleast implicitly convertible to that?

    • srt1104

      Last comment was a bit ambiguous and there was no option to edit/delete so here goes.

      Also in the general sense of a function prototype, user-defined conversions do not have a return type but the function identifier itself is a type-name so doesn't the compiler check that what we are returning from the function is atleast implicitly convertible to that type-name?

    • nascardriver

      Return-values are copy-initialized from whatever comes after `return`

      Both are equally good, because the compiler knows what type `returnvalue` has (From the function declaration).

      Because copy-initialization is used for returns, `return { /* ... */ };` won't work for explicit constructors.

      Conversion operators have a different syntax, but they're not breaking C++'s type-safety. Normal function rules apply.

  • Gamer_to_be

    why doesn't this work? printCents is a Dollars' member function.

    • nascardriver

      You probably don't have an `operator<<` that accepts a `Cents`. Please post your full code and error messages.

      • Gamer_to_be

        There is no error; instead I got '9' instead of '900.

        • nascardriver

          You're casting an `int` (`m_dollars`) to a `Cents`. You're not using your typecast operator. You need to cast the `Dollars` object if you want to use the typecase operator

  • Tom


    First of all, thanks for this website! It's amazing and I'm having so much fun with it.

    I have a question. I realized that with typecast overloading, we can replace overloading other operators like operator+ or operator*, because the compiler will cast our object to another type (e.g. MyClass to an int) and will use the normal operator (e.g. you can do cents + 5 on the Cents class without overloading operator+ because cents would cast to an int). So, if we have overloaded both a typecast an operator like operator*, which will take precedence? I guess it will be the operator, because the typecast is only done after it checks if there is a matching operator function, but I'm not entirely sure.

  • Mo

    I have this code:




    I don't entirely understand why the compiler warns me that operator+ is ambiguous. This only happens when I add the overloaded type cast (operator int() const()). When I remove the overloaded type cast, it compiles. Why isn't this ambiguous without the type cast as there are two functions (member and normal) when my parameters are both cents.

    This raises another question. When I'm not overloading typecasting and I have overloaded member and normal functions:

    And if execute cents1 + cents2, the member function is executed. Is there an order for which type of function is executed?

  • omar

    I don't know whats the problem with this code.

  • Gabe

    You mentioned that this is an example of an int being converted to a double, yet because it is done with uniform initialization, it causes an error. Perhaps use copy assignment instead?

Leave a Comment

Put all code inside code tags: [code]your code here[/code]