Borland Online And The Cobb Group Present:


August, 1994 - Vol. 1 No. 8

Letters - PREPOST.CPP error

The error that Mr. Funk's letter addresses has been corrected for the on-line versions of these articles. This article has been included for its further information regarding overloaded increment operators.

In the March 1994 issue of Borland C++ Developer's Journal, I believe there's a line missing from an example program. In Listing B of the article C++ Language tip - Increment- and decrement-operator overloading there's no return statement for the overloaded pre-increment operator member function of the Integer class. You'll need to add

return (Integer &)intValue;

to the end of the operator++() function.

If you try to compile the code as it appears in the article, the compiler warns about the function's lack of a return statement. Strangely, when I run the program without the return statement, the function displays 1048 instead of 2.

Alan Funk Houston, Texas

You're right, Alan, there's a line missing from the code's overloaded pre-increment function. As you said, the function should include a return statement.

Before we show the correction, let's talk for a moment about exactly what value an overloaded increment operator should return. In our original article on overloaded increment operators, we overloaded the increment operator for a class that contained integers. In that overloaded increment function, we incorrectly returned an integer value.

Typically, when you call the increment operator for a variable of a built-in data type, you ignore the return value. For example, the lines

int i=1;

i++;

declare the integer i, then call the increment operator to increment the value of i. However, the lines don't use the increment operator's return value.

The rewritten lines

int i=1, j=0;
j=i++;

declare the variables i and j, increment i, and store the incremented value of i in the variable j. As you can see, the increment operator returns a value that's the same type as the variable you increment.

For this reason, classes that overload the increment (and decrement) operator should return a value that's the same type as the incremented object. Continuing with our example, the lines

Circle myCirc(1), anotherCirc;

anotherCirc = myCirc++;

declare the two Circle class objects myCirc and anotherCirc, call the Circle class's overloaded increment operator, then store its return value in the anotherCirc object. As you can see, the Circle class's overloaded increment operator should return a Circle object.

In fact, your suggested repair line,

return (Integer &)intValue;

addresses this issue by returning an Integer object reference. However, there's a good reason you shouldn't return the value this way. When you cast the integer data member intValue into an Integer class reference, your program must create a temporary Integer class object to store this reference variable. To create the temporary object, your program must call the Integer class constructor, which is typically inefficient.

So how can overloaded pre-increment functions return reference variables that are references to objects of the class? Quite simply, they can use the this pointer.

Remember, to call the pre-increment operator, you specify an object of the class. Inside the pre-increment operator function, you have access to that object through the this pointer. By simply returning the incremented object's data, the function returns a reference to that object.

Listing A contains the corrected version of the Integer class in the PREPOST.CPP file. Notice the new return statement at the bottom of the overloaded pre-increment function in the Integer class definition.


Listing A: Corrected Integer class from PREPOST.CPP

class Integer
{
  public:
    Integer(int newValue = 0) :
      intValue(newValue) {}

    Integer& operator++()
      {
        cout << "Pre-increment\n";
        ++intValue;
        return *this; //add this line
      }

    Integer operator++(int)
      {
        cout << "Post-increment\n";
        Integer temp(*this);
        ++(*this);
        return temp;
      }

    operator int() const
      { return intValue; }

  private:
    int intValue;
};

By the way, if a function doesn't return a value, you'll almost always get strange return values when you call the function. Exactly what value an errant function returns depends on what's on the stack or in the AX register when the function exits.

Return to the Borland C++ Developer's Journal index

Subscribe to the Borland C++ Developer's Journal


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.