What Is Overloading?


In early programming languages, such as C, BASIC, FORTRAN, and Pascal, the name of every function in a program had to be unique. No two functions could have the same name. In C++, that's not the case. It's possible, and often desirable, to assign the same name to two or more functions; that's overloading.

There are two basic kinds of overloading. The first is function overloading, which involves having multiple functions with the same name. In addition, you can overload operators, such as + and *.

Let's first examine function overloading.

Overloading Functions

C++ allows functions in different classes to have the same name. That is not overloading.

Tip

When programmers talk about member functions, they often use the scope resolution operator to show which function they mean. If you use that style, the function you're talking about is clear. For example, it's easy to distinguish snert::Zop() from blarg::Zop(). It's clear that they are two different and unrelated functions in two different classes.


Why? Because the class name differentiates the functions. If two classes, one called snert and the other called blarg, each have a function named Zop(), the compiler differentiates between them by their types. The class that they are a member of tells the compiler which one to use. In fact, the compiler sees them as having nothing to do with each other even though they are both called Zop().

To be overloaded, the functions must be in the same class. Now why in the world would anyone want to have two functions in the same class with the same name?

In chapter 4, "Introducing the LlamaWorks2D Game Engine," you were able to both set and get the x location of a sprite object with a function called X(). Likewise, you were able to both set and get the y location with a function called Y(). This worked because the X() and Y() functions are overloaded. The sprite class contains one X() function that sets the x location of the sprite object and another that gets the x location. There are also two functions in the sprite class called Y() that set and get the y location, respectively. Using function overloading enables you to access the values of the private x and y data members using very intuitive function names. This style of programming helps reduce the number of function names you have to remember in order to use objects.

The first X() function in the LlamaWorks2D sprite class sets the value of the class's private data member x. Here's the source code for it:

 inline void sprite::X(int upLeftX) {     x=upLeftX; } 


As you can see, this function assigns the value of its parameter to the private data member x. Because LlamaWorks2D is a teaching tool as much as a game engine, I've purposely left out some error checking. For instance, this function should ensure that the value of upLeftX is on the screen.

The other version of the sprite::X() function gets the value of the private data member x. Here's its source code:

 inline int sprite::X() {     return (x); } 


All this version does is return x.

How can we, or the compiler for that matter, tell which overloaded function a program is calling? Like the compiler, we can differentiate between the functions by their return types and parameter lists. For example, the X() functions in the sprite class both have different return types and a different numbers of parameters. Therefore, if you see code like this:

 sprite theBall; theBall.X(100); 


you use the fact that this call passes a parameter to X() to determine which version of the function is being called. Because this call passes the value 100 to X(), it has to be calling the version with one parameter. That version sets the x location of the sprite. It follows that if you see code like this:

 int ballX = theBall.(); 


you can tell which function is being called based on the return type and parameter list. The first version of X() in the sprite class requires one parameter and doesn't return a value, so the code can't be calling that one. The second version of X(), takes no parameters and returns an integer. That's the one that fits this usage.

Another reason C++ programmers use function overloading is to be able to provide different functions of the same name that all do the same thing in a slightly different way. Listing 5.1 gives an example of this.

Warning

You cannot have two functions in a class with the same name, parameter list, and return type. If you do, the compiler won't be able to tell them apart. Also, if two functions have the same name and parameter list but different return types, the compiler won't be able to differentiate between them.


Listing 5.1. A class with overloaded constructors

 1     class point_2d 2     { 3     public: 4         point_2d(); 5         point_2d(int xComponent, int yComponent); 6 7         void X(int xComponent); 8         int X(); 9 10        void Y(int yComponent); 11        int Y(); 12 13    private: 14        int x, y; 15    }; 16 17 18    point_2d::point_2d() 19    { 20       x=y=0; 21    } 22 23    point_2d::point_2d(int xComponent, int yComponent) 24    { 25       x=xComponent; 26       y=yComponent; 27    } 

Listing 5.1 contains a class called point_2d, which is a class you might use in a game. Notice that the class has two constructors. Their prototypes are on lines 45. The first takes no parameters and the second requires two parameters. The listing shows the code for these constructors on lines 1827. The first constructor, which is called the default constructor, initializes the x and y data members to 0. The second constructor initializes the x and y data members to the values passed in through the parameter list. These constructors enable programs to declare point_2d variables in the following ways:

 point_2d point1; point_2d point2(10,20); 


These two functions do essentially the same thing: they both initialize a new point_2d object. However, they do it in slightly different ways. Both ways of initializing this object are intuitive and useful to programmers. Therefore, it's sensible for the class to provide both functions. Function overloading enables it to do exactly that.

Tip

You can overload any function in a class except the destructor.


Overloading Operators

C++ enables you to create operators for your classes. Examples of operators are +, -, *, and /. It may seem odd to be able to create operators, but programmers find it really handy once they give it a try.

We all know how to use operators with integers. For instance, the addition operator for integers adds two numbers together. However, you can also define an addition operator for other types. One example is the string class that is defined in the C++ standard libraries. Suppose you saw the following code in a program:

 string thisString = "Mary had a "; string thatString = "little lamb."; string theOtherString = thisString + thatString; 


Looking at this code, most programmers expect the result in theOtherString to be "Mary had a little lamb." In this case, the + operator is used to combine the contents of two string variables. This is conceptually similar to adding two integer variables. Any time you want to perform an operation on a class that is conceptually similar to addition, you can define a plus operator for that class. The same is true of other operators.

The best way to explain how to overload operators is to demonstrate it. I'll do that by creating a class to represent mathematical vectors in the next section.



Creating Games in C++(c) A Step-by-Step Guide
Creating Games in C++: A Step-by-Step Guide
ISBN: 0735714347
EAN: 2147483647
Year: N/A
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net