Overloading

Functions in C

In C, everything is simple

  • A function has a name

  • The name is the only thing by which functions are distinguished

  • Not the return type, nor the paraameters

#include <stdio.h>

void f(int i)
{
    printf("%s\n", __PRETTY_FUNCTION__);
}
void f(char* s)
{
    printf("%s\n", __PRETTY_FUNCTION__);
}

Compiler complains:

code/c++03-overloading-c.c:7:6: error: conflicting types for ‘f’; have ‘void(char *)’
    7 | void f(char* s)
      |      ^
code/c++03-overloading-c.c:3:6: note: previous definition of ‘f’ with type ‘void(int)’
    3 | void f(int i)
      |      ^

Functions in C++ — Overloading

#include <iostream>

void f(int i)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void f(char* s)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


int main()
{
    int i = 42;
    f(i);

    char s[] = "howdy";
    f(s);

    return 0;
}
$ code/c++03-overloading
void f(int)
void f(char*)

Underlying Mechanism: Name Mangling

  • Originally, C++ compilers were frontends to C

  • Generated C code which was then compiled

  • Times have changed, but not so much

  • ⟶ still compatible with C

  • ⟶ C++ and C can be mixed

How is overloading implemented?

  • Function names are mangled

  • ⟶ contain their parameter types

$ nm code/c++03-overloading
...
0000000000401176 T _Z1fi
00000000004011a0 T _Z1fPc
...
$ nm --demangle code/c++03-overloading
...
0000000000401176 T f(int)
00000000004011a0 T f(char*)
...

Overloading Class Methods: Just The Same

The pointless class point from Classes and Objects has a method move(int, int) which takes two parameters which represent the respective x and y coordinates by which to move the point in question:

class point
{
public:
    // ...

    void move(int x, int y)
    {
        _x += x;
        _y += y;
    }

};

Overloading permits the class to have an alternative method which takes a single parameter, the vector by which to move the point:

class point
{
public:
    // ...

    void move(point vec)
    {
        _x += vec._x;
        _y += vec._y;
    }

};