5 Returning objects

Comparison operators always return bool values. However, other operators, such as = and + and etc., return an object of the same type as the operands.

For example, if i and j are both ints, then i+j returns an int. We'd like to do the same thing, but with user defined classes.

In C++ (and actually in C, as well), you can return an object.

class X
{
    int i,j;
  // ...
  public:
    int getI(void); // get the value of i
    int getJ(void); // get the value of j
    bool operator== (X b); // equality check
    X operator+ (X b);
};

X X::operator+(X b)
{
  X tmp;

  tmp.i = i + b.i;
  tmp.j = j + b.j;
  return tmp;
}

Observe that the + operator does not change either operand. Instead, a temporary object tmp is created to store the sum of *this and b. The temporary object is then used to specify the return value. This means the return value is just an X object that can be used just like any other X objects. For example, we can have the following code:

{
  X x,y;

  // ...
  x = (x == y) ? (x + y) : ((x + x) + y); 
}

Note that parantheses are added to emphasize the order of operations, and also operands of operators.

Sometimes, it is useful to return an lvalue. An lvalue is essentially a reference to an object in memory. Let us observe the following class:

class IntArray
{
    int array[256];
  public:
    int &operator[](unsigned u);
};

In this example, the class IntArray is merely a wrapper. However, you can easily extend it to have dynamic resizing, bound checking and other enhancements to the built-in array types. Let us consider how the indexing ([]) operator is used:

{
  IntArray someInts;

  someInts[0] = 45;
}

Here, the return value of the invocation of IntArray::operator[] is used to store a value. This is why the return type of this operator is int & and not just int.

int & is a reference to an int. In other words, a value of this type can appear on the left hand side of an assignment operator (hence the name lvalue). A return type of int, on the other hand, specifies a value of type int. An int return value cannot appear on the left hand side of an assignment operator because it does not indicate where to store a result. In other words, a return type of int is not an lvalue.

Now that we have seen the class definition and use of IntArray, let's finish up the discussion with the definition of IntArray::operator[]:

int &IntArray::operator[](unsigned u)
{
  // .. bound checking code that can
  // potentially throw exceptions
  return array[u];
}

That's it! Although array[u] seems to specify just an int value (and not a reference to an int), the compiler understands the return type of a reference to an int. As a result, the compiler generates the code to return the reference of array[u] (essentially a pointer in terms of implementation), rather than the value of array[u].

Copyright © 2006-09-12 by Tak Auyeung