It is perfectly consistent.
Polymorphism (in the OOP sense) is when the method called is determined
when the program is running. Everything else --overloads, operators, templates, etc-- are determined
before the program ever runs.
To make it clear, let's play compiler for a moment.
The includes we'll need:
1 2
|
#include <iostream>
using namespace std;
|
Suppose we have a template class that overloads a method called "add" which adds two points together.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
struct point_t
{
int x, y;
point_t( int x = 0, int y = 0 ): x( x ), y( y ) { }
// first overload
point_t add( const point_t& pt )
{
return point_t( x +pt.x, y +pt.y );
}
// second overload
point_t add( int x, int y )
{
return point_t( this->x +x, this->y +y );
}
};
|
For your convenience at home, we'll also add an ostream insertion operator. We will totally ignore it for the purposes of this discussion. (You can think about it later.)
1 2 3 4 5
|
ostream& operator << ( ostream& outs, const point_t& pt )
{
outs << '(' << pt.x << ',' << pt.y << ')';
return outs;
}
|
So far, so good. Using the class is a breeze.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
int main()
{
point_t a( 10, 20 );
point_t b( 5, -7 );
point_t r;
// first overload
r = a.add( b );
cout << a << " + " << b << " = " << r << endl;
// second overload
r = r.add( r.x *10 -r.x, r.y *10 -r.y );
cout << "scaled by 10 = " << r << endl;
return 0;
}
|
Now, the question is: "is this polymorphic?"
To answer it, we'll pretend we are the compiler.
Initializations
First, we read everything and remember what stuff looks like. When we finally get to
int main()
we begin outputting executable instructions. We initialize the program and all the stuff outside the scope of our discussion.
Ok, now we get to line 3. We allocate room for a
point_t, set
x and
y to 10 and 20, and remember its name is "a".
Likewise for line 4.
Line 5 is interesting. It is
not overloaded, but it has
default arguments. We are a smart compiler, so we set
x and
y both to zero.
First Overload
Now for the interesting stuff: line 8.
The user wants to use
r's
add() method. But there are two different versions of it defined.
So what we do is look to see if we can find a version of
add() that takes the given type of argument: another
point_t. Fortunately there is one (up on line 7 of the class specification), so that's the one we will use.
We compile line 8 using the first version of
add().
Second Overload
Continuing on our way, we eventually get to line 12 and discover another call to
add(). This time, however, we notice that the function is called with two
int arguments. And again, we remember that line 13 above defines a version of
add() that takes exactly that.
So we use the second version of
add() to compile line 12.
Etc.
Reflections
In both cases, we were able to determine the exactly which function to call based on its "signature", or the types of its parameters. As a result we were able to compile the program exactly and it will run using the correct version of each function.
Since everything was done at compile-time, (and the function called cannot change at runtime), the answer to our question is "No, it is not polymorphic."
OK, so let's see some polymorphism in use...
(to be continued...)