As you begin defining your own classes using Borland C++, you'll probably define member functionsfunctions that belong to your classes. In addition, you may want to add operator overloadingsupport for various operators in your classes.
For example, you may want to use the pre-increment (++x) or post-increment (x++) operator with objects of one of your classes. The meaning of these operations will be fairly obviousthey'll typically behave the same with your classes as they do with the built-in types (int, char, int*, and so on).
However, understanding what happens when you overload the operator
() function call operator for a class is more difficult because
there's no definition for using this operator with variables
of the built-in types. In this article, we'll show you
how to overload the function call operator in your own classes.
Since there isn't a predefined meaning for operator
(), you're free to implement any behavior that seems
appropriate. In addition, you can specify any return type and
as many arguments as you'd like when you define operator
(). Unfortunately, a number of questions come to mind.
You'll want to overload operator () in three instances: single-function classes, array subset subscripting, and multidimensional array indexing. A single-function class has only one function (besides the constructors and destructors) that the user will call in normal situations. For example, you might want to create a number-averaging class that maintains a running average of a series of numbers. For this class, you could define operator () to accept a new number as the only argument and return the resulting average.
When you use operator () to implement subset subscripting, you're specifying that you want to retrieve multiple items from the array. A common form of this is an operator () function that retrieves a substring from a string class based on position and length.
For a multidimensional array class, you can use operator ()
to implement subscripting. One reason to do this is that the syntax
you use to call operator () is similar to that of the
subscript operator, operator [].
You call operator () the same way you specify an element
of an array with the subscript operator. For example, if you define
a four-dimensional array class FourDArray and create
an object named fourD, you can access a specific element
of the array with the statement
fourD(4,2,2,22)
If you're calling operator () on a single function
class and you've declared it to take no parameters, you'll
use the statement
item()
to call operator () on the object named item.
Perhaps the most confusing aspect of defining operator ()
is the syntax of declaring the operator itself. Inside a class
declaration, the syntax
int operator () ();
declares operator () to accept no parameters and return an integer value. In this statement, the first set of parentheses specifies the name of the operator, and the second set specifies the argument list for the overloaded operator.
If you want to pass one or more parameters to operator (),
you'll add the argument types and identifiers within the
second set of parentheses. To declare operator () for
the number-averaging class described earlier, you might write
float operator () (float newNumber);
Therefore, the statement
avg(86.4)
is equivalent to
avg.operator () (86.4)
as far as the compiler is concerned, although it's unlikely that you'd see anyone use the second form.
Finally, you can define operator () as a nonstatic member
function only. It can't be a static function, because you
must call it with an instance of its class. (This is similar to
the idea that you must first have an array of characters before
you can use operator [] to retrieve an element of the
array.)
To put operator () into action, let's create a program that calculates a running average of floating point values. To begin, launch the Borland C++ 3.1 Integrated Development Environment (IDE) for DOS. (This program works with Borland C++ 4.0 as well.)
When the IDE's desktop appears, choose New from the File menu to open an editor window for a new source file. When the new window appears, enter the code from Listing A.
Listing A: AVERAGER.CPP
#include <iostream.h> class Averager { public: Averager() { total = 0; itemCount = 0; } float operator () (float item) { total += item; ++itemCount; return total/itemCount; } private: float total; int itemCount; }; int main() { Averager avg; float newValue = 0; do { cout << "Enter new value "; cin >> newValue; cout << "Average is " << avg(newValue); cout << endl; } while (newValue != -1); return 0; }
When you finish entering the code, choose Save from the File menu. In the Save File As entry field of the Save File As dialog box, enter AVERAGER.CPP. Click OK to save the file.
To run the program, choose Run from the Run menu. The compiler
will build the program and then run it. When
Enter new value
appears on the screen, enter 88, 93.6, 89, 92.9, and 45.1 as new values. When you enter the last number, the output from the program should be similar to what appears in Figure A.
Figure A - The AVERAGER program simply calculates a running average with a single-function class.
Enter new value 88 Average is 88 Enter new value 93.6 Average is 90.800003 Enter new value 89 Average is 90.200005 Enter new value 92.9 Average is 90.875 Enter new value 45.1 Average is 81.720001
To end the program and return to the IDE, enter -1. To
exit the IDE, choose Quit from the File menu.
The syntax of overloading the function call operator confuses
many programmers when they see it for the first time. However,
if you know how to apply this syntax, you can overload operator
() to provide an appropriately simple interface for your
own classes.
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.