Werteübergabe an eine Funktion

Es ist wichtig zu verstehen, was passiert, wenn man eigene Variablen an eine Funktion übergibt. In C++ gibt es 2 verschiedene Arten dies zu tun. Diese sind als „Call by Value“ und „Call by Reference“ bekannt. Wie eine Funktion ihre Werte entgegen nimmt, bestimmt sie in ihrem Funktionskopf, wo sie in der Parameterliste die zu übergebenden Typen als Parameter an die Funktion festlegt:
void byValue(std::string i);
void byReference(std::string& i);
void byPointer(std::string* i);


Die Übergabe des Parameters in die Funktion als Referenz oder Pointer bewirkt hierbei, das nur die Referenz bzw. der Pointer kopiert werden. Wenn man in eine Funktion einen String per value übergibt, bewirkt dies eine vollständige Kopie des Strings. Alles was mit dem String in der Funktion passiert, wird sich nicht auf die Ursprünglich übergebene Stringinstanz aus. Anders wenn man eine Referenz oder einen Pointer auf den String übergibt, hier greift dann die Funktion auf die ursprüngliche Stringinstanz zu. Wenn eine Funktion einen übergebenen Parameter nicht verändert, sollte man ihn const deklarieren, damit auch der Aufrufer weiß, dieser Wert wird nicht verändert.
Manchmal kommt die Frage, welches von beiden nun das bessere ist. So pauschal kann man das nicht sagen, es kommt hierbei eigentlich immer auf den übergebenen Typen an. Bei den C++ eigenen einfachen Standardtypen (z.B. int, float oder double) ergibt die Übergabe per Call by Reference nur Sinn, wenn der übergebene Parameter die ursprüngliche Variable manipulieren soll. Bei einer Klasse wie std::string oder std::vector hingegen führt die Übergabe per Value zu einer unnötigen Kopie, da der gesamte Inhalt des Strings oder Vectors hierbei in ein neues Objekt kopiert werden muss, welches dann nur innerhalb der Funktion benutzt wird. Deshalb empfiehlt sich hier die Übergabe als Referenz.

Funktionen überladen


Funktionen lassen sich in C++ überladen, das heißt, es kann mehrere Funktionen mit dem gleichen Namen, aber verschiedenen Typen als Parameter geben:
void ausgabe(int i)
{
    std::cout << i << std::endl;
}
void ausgabe(float f){...}
void ausgabe(std::string s){...}


Mit diesen 3 Funktionen lässt sich also jeweils ein int, float oder std::string ausgeben.
Jede der Funktionen kann dann für ihren eigenen Typ die Aufgabe der Funktion konkret implementieren.