Anhang B. Funktionsobjekte

In diesem Anhang:

Funktor

Ein Funktionsobjekt ist ein Objekt, das sich wie eine Funktion verhält. Erreicht wird das durch das Überladen des Klammeroperators in C++. Ein Funktionsobjekt wird in der C++-Community gern auch als Funktor bezeichnet. Dem Python-Programmierer sind Funktionsobjekte unter dem Namen callable object ein Begriff.

Wie funktioniert ein Funktionsobjekt?

Ein Funktionsobjekt lässt sich wie eine Funktion aufrufen. Daher ist es naheliegend, einem Funktionsobjekt einen Funktionszeiger gegenüberzustellen. Listing B.1 enthält die Funktion lessLength und das Funktionsobjekt GreaterLength. Beide sind in Aktion im Kapitel 3, Abschnitt „Lambda-Funktionen“ zu sehen. Sie sortieren mithilfe des STL-Algorithmus std::sort den Vektor über Strings in aufsteigender bzw. absteigender Ordnung.

operator()

Entscheidend für das Verständnis des Funktionsobjekts ist der Klammeroperator operator(). Er sorgt dafür, dass Objekte dieser Struktur von der C++-Laufzeit als Funktionen behandelt werden. Im Ausdruck std::sort wird GreaterLength() instanziiert und als Sortierkriterium verwendet. Natürlich müssen die Argumente, die der Algorithmus std::sort erwartet, wenn er einen Vektor von Strings sortieren soll, mit den Parametern des Klammeroperators zusammenpassen.

Die wichtigste Frage bleibt bestehen. Betrachten wir die Funktion LessLength und das Funktionsobjekt GreaterThen in Listing B.1 genauer, fällt lediglich auf, dass mehr Schreibarbeit notwendig ist, um das Funktionsobjekt zu definieren. Die Antwort auf die Frage „Welche Vorteile bietet ein Funktionsobjekt?“ lässt sich vereinfacht auf ein Wort reduzieren: Zustand.

Zustand

Ein Funktionsobjekt ist ein Objekt mit Methoden und Attributen und kann insofern einen Zustand besitzen. Das einfache Listing B.2 addiert die Werte eines Vektors und stellt das Ergebnis über die Methode getSum() zur Verfügung. Im Attribut sum wird der Zustand des Objekts gehalten.

sumMe.cpp

Der Algorithmus std::for_each besitzt die besondere Eigenschaft, dass er das Funktionsobjekt zurückgibt (Zeile 29), das in diesem konkreten Fall das Ergebnis der Summation hält.

Das Ergebnis ist relativ unspektakulär: