Skip to content
Snippets Groups Projects
Commit ae32e74d authored by Marcus Mohr's avatar Marcus Mohr
Browse files

Adds a first notebook on overloading

In the notebook we demonstrate overloading of free functions and discuss
the question of a function's signature.
parent 101cc0e6
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id:235e90d0-cc51-48c6-9df4-399338da447a tags:
# Overloading
In C++ functions that expect different types or numbers of parameters can still have the same name. This is called **overloading** and constitues a form of **static polymorphism**.
%% Cell type:markdown id:90ce7880-230c-4723-bbb0-09bb0ce9be7e tags:
### Example #1
We are going to implement two free-functions that return the magnitude of their argument.
%% Cell type:code id:eec83314-77dd-473c-9350-74d59ee80a28 tags:
``` C++17
// Version for int
int getMagnitude( int input ) {
return input > 0 ? input : -input;
}
```
%% Cell type:code id:bdf6437f-1345-4341-89ad-2e1bfccf3f51 tags:
``` C++17
// Version for double
double getMagnitude( double input ) {
return input > 0.0 ? input : -input;
}
```
%% Cell type:code id:b729878a-62d9-4f61-89c5-a4cdaba10d17 tags:
``` C++17
// A driver to check that this works
int main() {
double dVal = -5.2;
std::cout << "|" << dVal << "| = " << getMagnitude( dVal )
<< ", |2| = " << getMagnitude( 2 ) << std::endl;
}
```
%% Cell type:markdown id:5b6c893e-1883-482c-8415-0ccdebfba63d tags:
Let's execute our program. In our notebook we can do this by invoking the main() function:
%% Cell type:code id:7ee16102-554c-45c2-8355-dc68d10b2243 tags:
``` C++17
main()
```
%% Output
|-5.2| = 5.2, |2| = 2
0
%% Cell type:markdown id:3b86fe70-835c-4358-9c46-f1b582327fa0 tags:
What's the last line with the 0?
%% Cell type:markdown id:6a52697f-6c1b-4561-8626-a56a75d80f75 tags:
### Example #2
%% Cell type:markdown id:d418a230-01d8-4d6b-a24b-c16bb3211f27 tags:
A simple function that echos its input to standard output
%% Cell type:code id:4229aeb8-1ec6-4fe1-b7fd-6a2fe4573255 tags:
``` C++17
void display( const std::string mesg ) {
std::cout << mesg << std::endl;
}
```
%% Cell type:markdown id:4f81e8dd-ee8c-4714-b9ae-a40e0099e671 tags:
Another version of display() which differs from the former in:
- expects a 2nd argument
- indents the string by depth blanks
%% Cell type:code id:c224bdfb-91a2-4519-acfb-183864ab4726 tags:
``` C++17
void display( const std::string mesg, int depth ) {
std::string indent( depth, ' ' );
std::cout << indent << mesg << std::endl;
}
```
%% Cell type:markdown id:4468de2f-f108-41b2-a8c5-2d4c49d79987 tags:
Let's use both to do some simple drawing
%% Cell type:code id:d1acaf75-c148-4aa8-a407-d2391a64fd33 tags:
``` C++17
int main() {
const int len = 5;
std::string stars( len, '*' );
display( stars );
for( unsigned int k = 1; k < stars.length(); k++ ) {
display( stars.substr( k ,std::string::npos ), k );
}
}
main()
```
%% Output
*****
****
***
**
*
0
%% Cell type:markdown id:e381e911-aa5c-43bd-a3d5-2c25a7a0ab3e tags:
### Example #3
We want to implement two functions that return a zero for initialising new variables.
%% Cell type:markdown id:482d9fcc-e25f-4be2-883c-8c10e7b0ffaf tags:
The magic command **%%file** will write the contents of the cell to the given file
%% Cell type:code id:a0160540-141d-49a8-a16b-0832deb45111 tags:
``` C++17
%%file example.cpp
int zero() {
return 0;
}
double zero() {
return 0.0;
}
int main() {
double dVal = zero();
int iVal = zero();
}
```
%% Output
Overwriting example.cpp
%% Cell type:markdown id:5e2ece20-14ea-4eab-b147-c2056abcb54d tags:
Now let's check whether GCC will compile it?
%% Cell type:code id:ecd5b116-b2f7-453f-9bdf-fd4d424f5161 tags:
``` C++17
!g++ example.cpp
```
%% Output
example.cpp: In function ‘double zero()’:
example.cpp:5:8: error: ambiguating new declaration of ‘double zero()’
double zero() {
^~~~
example.cpp:1:5: note: old declaration ‘int zero()’
int zero() {
^~~~
%% Cell type:markdown id:2c71fc09-d97c-4f25-ba9e-cd013edda551 tags:
Wasn't aware that 'ambiguate' was a noun ;-) Let's see what clang will tell us
%% Cell type:code id:3cb990eb-aef8-464b-ac85-644c0d7b57c2 tags:
``` C++17
!clang++ example.cpp
```
%% Output
example.cpp:5:8: error: functions that differ only in their return type cannot be overloaded
double zero() {
~~~~~~ ^
example.cpp:1:5: note: previous definition is here
int zero() {
~~~ ^
1 error generated.
%% Cell type:markdown id:1e494c0f-d7a1-4412-b67b-5911f5d7d46b tags:
Okay, so apparently overloading does not work, for **'functions that differ only in their return type'**.
Well, we might remember that the **signature of a function** consists of the number and type of its arguments, but not its return type.
We can check on that by the following:
%% Cell type:code id:91797c03-d79d-446d-946a-1ecdd8184f44 tags:
``` C++17
%%file signature.cpp
int getMagnitude( int input ) {
return input > 0 ? input : -input;
}
double getMagnitude( double input ) {
return input > 0.0 ? input : -input;
}
int getMagnitude( short input ) {
return input > 0 ? input : -input;
}
void demo( double dVal, float fVal, int* iPtr ){};
```
%% Output
Overwriting signature.cpp
%% Cell type:code id:07ca2086-0fc4-41df-8061-40aa13bc7f67 tags:
``` C++17
!g++ -c signature.cpp
```
%% Cell type:code id:773be3ed-09bb-48bc-9af6-75a6156db75c tags:
``` C++17
!nm -C signature.o
```
%% Output
0000000000000014 T getMagnitude(double)
0000000000000000 T getMagnitude(int)
0000000000000046 T getMagnitude(short)
000000000000005b T demo(double, float, int*)
%% Cell type:code id:275f2c22-6b23-45bd-b628-7d2b998a8da5 tags:
``` C++17
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment