Function overloading

1) Make sure that you are in the
cppTutorials directory.

2) Create a new directory named functionOverload
> mkdir functionOverload

3) change the current working directory to be the functionOverload directory:
> cd functionOverload

4) open up a new file named functionOverload.cpp and place the following in the file (cut and paste):
//--------------------------
#include <iostream>

//Three functions with the same name but different
//arguments
int multiply(int num1, int num2){return num1*num2;}
float multiply(float num1, float num2){return num1*num2;}
int multiply(int num1, int num2, int num3){return num1*num2*num3;}

int main()
{
  int m23,m234;
  float mf2pi;
  float xVal = 2.0;
  float yVal = 3.14;

  m23 = multiply(2,3);
  mf2pi = multiply(xVal,yVal);
  m234 = multiply(2,3,4);

  std::cout << "m23 = "<<m23<<std::endl;
  std::cout << "mf2pi = "<<mf2pi<<std::endl;
  std::cout << "m234 = "<<m234<<std::endl;
}
//--------------------------

5) You should notice that we created three different functions that all have the same name!
The compiler will decide which function to use by checking what kind of arguments you
have provided to the overloaded function named "multiply". This multiple assignment
of a function name is called "function overloading". In the above code, we first call
the "multiply" function using two integers, the second call uses two floating point arguements,
and the last call of the "multiply" function will use three integer values for the argument list.

5) Download the Makefile

6) Run make:
> make

7) Run the code:
> ./functionOverload
This is what I get when I run the code:
-------------------------------------------
mike functionOverload> ./functionOverload
m23 = 6
mf2pi = 6.28
m234 = 24
mike functionOverload>
-------------------------------------------

8)  The  ability to overload a function is not only for user defined functions. We can also
overload operators! We will do an example where the plus operator "+" is overloaded.

9) Open up the functionOverload.cpp file and place a structure near the top so that your code
looks like:
//--------------------------
#include <iostream>

//A structure with two floating point elements "x" and "y"
struct vec2d{
  float x;
  float y;
};
.
.
.
//--------------------------
Note: A structure is a declaration type. The compiler has, in addition to integers and floats and vectors,
a new type of data that contains two floats as one thing. This thing is called a "structure".
In Fortran this would be a "common block". A structure can contain all possible data types. It can
even include other structures.

10) Now inside of the "main" program make your code look like:
//--------------------------
.
.
.
int main()
{
  int m23,m234;
  float mf2pi;
  float xVal = 2.0;
  float yVal = 3.14;
  vec2d aVec;
  vec2d bVec;
  vec2d cVec;
  aVec.x = 2;
  aVec.y = 3;
  bVec.x = 4;
  bVec.y = 5;
.
.
.
}
//--------------------------
Note: We have now declared three data structures aVec, bVec, and cVec, that have the
structure data type "vec2d" that we defined earlier. We then defined the individual elements
of aVec and bVec using the "." syntax. For example, to access the element "x" within aVec
we write "aVec.x". In our code we set the value of "x" within "aVec" to be equal to the
value 2.

11) We are now going to overload the "+" operator. Make your code look like
//--------------------------
#include <iostream>

//A structure with two floating point elements "x" and "y"
struct vec2d{
  float x;
  float y;
};

//Overload the "+" operator
vec2d operator + (const vec2d &p1, const vec2d &p2) {
  vec2d xyVec;
  xyVec.x = p1.x + p2.x;
  xyVec.y = p1.y + p2.y;
  return xyVec;
}
.
.
.

//--------------------------
Note: We have a function that takes the arguments "&p1" and "&p2". These arguments
have a type declaration of "const vec2d". The declaration says that "&p1" and "&p2" are
"vec2d" structures that are constant (can NOT be altered). The code "vec2d operator..."
says that the operator will return a structure of type "vec2d". The function creates a data type
named "xyVec" that is declared as a "vec2d" structure. The "xyVec" structure is then filled
with the vector addition of "p1" and "p2". After the "xyVec" has been filled, the function
returns the "xyVec" structure.

Note: You might be asking why we have "&p1" in the argument list but "p1" in the code.
The "&" before "p1" says to use a pointer to the memory address of "p1". The syntax is as
follows:
if I have a variable called "thing", I need to declare what type of thing "thing" is. For example
I can declare "thing" to be an interger by stating:
int thing;
This integer variable "thing" will be assigned a memory address by the compiler.
In C and C++, I can work with the variable OR the variable address. The address of "thing"
will be something called a "pointer". This pointer (or memory address) is defined as "&thing".
The "&" says get the memory location of "thing". I can make a pointer to a thing using the syntax:
thingPointer = &thing;
If I want to get the value of "thing" from the "thingPointer" I can write "*thingPointer". The "*"
says get the value stored at the memory location "thingPointer". In short:

int thing //--> An integer "thing"

thingPointer = &thing //--> Pointer to a memory location

*thingPointer //--> The value held at the memory location "thingPointer" 

12) We are almost done. Make your main code look like:
 
//--------------------------
.
.
.
int main()
{
.
.
.
  aVec.x = 2;
  aVec.y = 3;
  bVec.x = 4;
  bVec.y = 5;

  cVec = aVec + bVec;
  std::cout << "cVec = "<<cVec.x<<" "<<cVec.y<<std::endl;
.
.
.
}
//--------------------------

13) Compile the code:
> make

14) Run the code:
> ./functionOverload

This is what I get:
------------------------------
mike functionOverload> ./functionOverload
m23 = 6
mf2pi = 6.28
m234 = 24
cVec = 6 8
mike functionOverload>
------------------------------
Note: We have now overloaded the "+" operator so that the addition of two
vectors is defined!