4 Stimmen

Was ist die typische Verwendung von operator()

Mögliches Duplikat:
Wie kann das Überladen des Operators "Funktionsaufruf" in C++ nützlich sein?

Ich sehe oft, wo der Klammeroperator, operator() auf eine Klasse oder Struktur überladen wird. Ich bin selbst noch nie auf eine solche Notwendigkeit gestoßen und frage mich, was die typische Verwendung/Bedarf dieses Operators ist?

Zum Beispiel kann das Überladen operator== wird als wahr oder falsch zurückgegeben, je nach Gleichheit mit dem angegebenen Argument. Dies hat ein bestimmtes akzeptiertes und erwartetes Verhalten.

3voto

Andrew Punkte 2484

Sie wird häufig für die Hashes, Mengen und Algorithmen der STL-Komponente verwendet, um sogenannte "Funktoren" zu konstruieren. Zum Beispiel:

using stl::map ;

map<string, string> myMap ;

aber wenn Sie sich die Spezifikation für map ansehen, enthält sie auch einen 'Compare'-Eintrag, der standardmäßig auf less eingestellt ist. Compare ist der "Funktor", den map beim Vergleich zweier Schlüssel verwenden soll. Er sieht in etwa so aus:

template<class Key>
class less<Key> {
public:
  boolean operator()(const Key& a, const Key& b) { return a < b ;}
} ;

Was Sie also haben, ist:

 map<string, string, less<string> > myMap ;

und jedes Mal, wenn man etwas in die Karte einträgt oder versucht, etwas in der Karte zu finden, wird der less::operator() verwendet, um die Vergleiche durchzuführen.

Sie können dies verwenden, um andere Effekte zu erzielen, z. B. bei der Verwendung von "sort" können Sie sort dazu bringen, Elemente in umgekehrter Reihenfolge zu liefern, indem Sie einen anderen Funktor verwenden.

0voto

jwd Punkte 10217

Sie können operator(), auch bekannt als Funktionsaufrufoperator, verwenden, um ein Objekt wie eine Funktion zu behandeln (und als solche zu verwenden).

Diese Objekte werden oft als "Funktoren" bezeichnet, aber das sollte nicht mit dem gleichen Begriff aus der Mathematik verwechselt werden. Ich glaube, der korrektere Begriff ist "Funktionsobjekt".

Stellen Sie sich vor, Sie haben eine Funktion, die einen Rückruf annimmt. Aber nehmen Sie an, Sie müssen einen Zustand in diesem Rückruf speichern.

(Anmerkung: Ich habe diesen Code nicht kompiliert, aber Sie verstehen die Idee)

void DoStuffAndCallBack(MyCallbackType Callback)
{
    ...
    Callback(args)
    ...
}

In C oder in C++ mit Klassen würden Sie dieser Methode eine statische Callback-Funktion übergeben und die Ergebnisse in einer globalen oder klassenstatischen Variablen speichern.

Aber in C++ könnte die Funktion so geschrieben werden:

template<CallbackType>
void DoStuffAndCallBack(CallbackType Callback)
{
    ...
    Callback(args)
    ...
}

Jetzt können Sie ein Funktor-Objekt definieren, das die folgenden Funktionen überlädt operator() und übergeben eine Instanz dieses Objekts an die Funktion. Diese Instanz erhält den Rückruf, und alle Zwischenergebnisse, die Sie speichern möchten, können in diesem Instanz .

Mit anderen Worten, es ist ein guter Weg, um Globals zu vermeiden (:

Ich bin mir sicher, dass es noch andere Verwendungszwecke gibt, aber das ist ein guter, IMO.

-2voto

jeffknupp Punkte 5616

Das kanonische Beispiel ist für eine intelligente Zeigerklasse, die zurückgibt, ob sie null ist oder nicht, so dass Sie Dinge wie tun können:

SmartPointer p = someOtherThing;
if (p) 
{ 
// do something 
}

In diesem Fall sollte der Rückgabetyp des ()-Operators bool sein, und der Code wird wie geschrieben funktionieren. Es wird ein Funktor erstellt, mit dem die Instanz der Klasse wie eine Funktion aufgerufen werden kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X