Ich versuche zu verstehen, was Mehrfachversand ist. Ich lese viele verschiedene Texte, aber ich habe immer noch keine Ahnung, was Mehrfachversand ist und wozu er gut ist. Vielleicht fehlt mir ein Stück Code mit Mehrfachversand. Können Sie bitte ein kleines Stück Code in C++ mit Mehrfachversand schreiben, damit ich sehen kann, dass es nicht richtig kompiliert/ausgeführt werden kann, weil C++ nur Einzelversand hat? Ich muss den Unterschied sehen. Danke.
Mehrfachversand in C++
Martin
Multi-Dispatch ist die Möglichkeit, basierend auf dem Laufzeittyp der an den Funktionsaufruf übergebenen Argumente auszuwählen, welche Version einer Funktion aufgerufen werden soll.
Hier ist ein Beispiel, das in C++ nicht richtig funktioniert (ungetestet):
class A { };
class B : public A { };
class C : public A { }
class Foo
{
virtual void MyFn(A* arg1, A* arg2) { printf("A,An"); }
virtual void MyFn(B* arg1, B* arg2) { printf("B,Bn"); }
virtual void MyFn(C* arg1, B* arg2) { printf("C,Bn"); }
virtual void MyFn(B* arg1, C* arg2) { printf("B,Cn"); }
virtual void MyFn(C* arg1, C* arg2) { printf("C,Cn"); }
};
void CallMyFn(A* arg1, A* arg2)
{
// ideally, with multi-dispatch, at this point the correct MyFn()
// would be called, based on the RUNTIME type of arg1 and arg2
pFoo->MyFn(arg1, arg2);
}
...
A* arg1 = new B();
A* arg2 = new C();
// Using multi-dispatch this would print "B,C"... but because C++ only
// uses single-dispatch it will print out "A,A"
CallMyFn(arg1, arg2);
-
Danke, diese Antwort ist so ziemlich das, was ich sehen musste. Jetzt muss ich nur noch herausfinden, warum zum Teufel jemand so etwas braucht. Trotzdem danke für das gute Beispiel.
– Martin
17. November 09 um 15:50 Uhr
-
Eine Anwendung ist Physik, ein Würfel, der mit einem anderen Würfel kollidiert, ist eine Kreuzung, ein Würfel, der mit einer Ebene kollidiert, ist eine andere Kreuzung. Daher haben Sie am Ende eine ganze Reihe verschiedener Methoden zur Kollisionserkennung, und das Dispatching ist dafür ziemlich nützlich. Hier ist ein Thread zum Thema Double Dispatch, gamedev.net/topic/453624-double-dispatch-in-c
– QuantenKarl
10. April 12 um 13:34 Uhr
-
Eine weitere Anwendung findet sich in Programmiersprachen. Angenommen, Sie möchten, dass der Plusoperator (‘+’) ein ganzzahliges Ergebnis berechnet, wenn beide Argumente Ganzzahlen sind, ein Float, wenn eines der Argumente ein Float ist, und eine verkettete Zeichenfolge, wenn beide Argumente Zeichenfolgen sind. Sie haben eine Hierarchie von Typen, die von “Ausdruck” abgeleitet sind, also möchten Sie, dass die Funktion, die aufgerufen wird, wenn Sie add(exp1,exp2) oder expr1->add(expr2) sagen, von den tatsächlichen Typen von exp1 und exp2 abhängt.
– seattlecpp
9. Mai 17 um 18:13 Uhr
Mehrfachversand liegt vor, wenn die ausgeführte Funktion vom Laufzeittyp von mehr als einem Objekt abhängt.
C++ hat Single Dispatch, denn wenn Sie virtuelle Funktionen verwenden, hängt die tatsächlich ausgeführte Funktion nur vom Laufzeittyp des Objekts links von -> oder ab. Operator.
Ich habe Mühe, an einen echten Programmierfall für den Mehrfachversand zu denken. Vielleicht in einem Spiel, in dem verschiedene Charaktere gegeneinander kämpfen.
void Fight(Opponent& opponent1, Opponent& opponent2);
Der Sieger eines Kampfes kann von den Eigenschaften beider Gegner abhängen, daher möchten Sie möglicherweise, dass dieser Aufruf abhängig von den Laufzeittypen beider Argumente an eines der folgenden gesendet wird:
void Fight(Elephant& elephant, Mouse& mouse)
{
mouse.Scare(elephant);
}
void Fight(Ninja& ninja, Mouse& mouse)
{
ninja.KarateChop(mouse);
}
void Fight(Cat& cat, Mouse& mouse)
{
cat.Catch(mouse);
}
void Fight(Ninja& ninja, Elephant& elephant)
{
elephant.Trample(ninja);
}
// Etc.
Was die Funktion tut, hängt von den Typen beider Argumente ab, nicht nur von einem. In C++ müssen Sie dies möglicherweise als virtuelle Funktionen schreiben. Eine virtuelle Funktion würde abhängig von einem Argument (dem this-Zeiger) ausgewählt werden. Dann muss die virtuelle Funktion möglicherweise einen Schalter oder etwas anderes enthalten, um etwas Bestimmtes mit dem anderen Argument zu tun.
-
Ein praktisches, häufig vorkommendes Beispiel ist, verschiedene Unterklassen unterschiedlich von einem Array von Basisklassenzeigern zu behandeln.
– kizzx2
26. August 2010 um 15:06 Uhr
Philipp Ngan
In Einzelversand die ausgeführte Funktion hängt nur vom Objekttyp ab. In
doppelter Versand die ausgeführte Funktion hängt vom Objekttyp und einem Parameter ab.
Im folgenden Beispiel ist die Funktion Area()
wird mit Single Dispatch aufgerufen, und Intersect()
basiert auf doppeltem Dispatch, da es einen Shape-Parameter verwendet.
class Circle;
class Rectangle;
class Shape
{
virtual double Area() = 0; // Single dispatch
// ...
virtual double Intersect(const Shape& s) = 0; // double dispatch, take a Shape argument
virtual double Intersect(const Circle& s) = 0;
virtual double Intersect(const Rectangle& s) = 0;
};
struct Circle : public Shape
{
virtual double Area() { return /* pi*r*r */; }
virtual double Intersect(const Shape& s);
{ return s.Intersect(*this) ; }
virtual double Intersect(const Circle& s);
{ /*circle-circle*/ }
virtual double Intersect(const Rectangle& s);
{ /*circle-rectangle*/ }
};
Darauf baut das Beispiel auf Artikel.
-
Ziemlich viele Plätze hast du da.
– Nachzügler
7. August 10 um 16:11 Uhr
-
@trager 2 zusätzliche Leerzeichen 🙂 Es wäre schön, wenn Stack Overflow es so formatieren könnte, wie viele Leerzeichen der Betrachter bevorzugt.
– pilch
16. März 12 um 12:09 Uhr
.
C++ unterstützt es nicht direkt, aber ich bin sicher, dass Sie dies irgendwie emulieren können. Ich habe nie MD verwendet oder auch nur ein nettes Design in anderen Sprachen gesehen, das mich dazu gebracht hat, MD in C++ zu haben. Dylan-Fanboys führen es als eines von Dylans Sprachfeatures auf. Aber soweit ich das beurteilen kann, riecht es nach schlechtem Design, weil die Anzahl der Funktionen, die Sie möglicherweise schreiben müssen, exponentiell wächst. Ich würde nicht so viele Funktionen schreiben wollen.
– Sellibitze
17. November 09 um 15:33 Uhr
Sie haben MD jedes Mal verwendet, wenn Sie die verwendet haben
Visitor
Muster.– Matthias M.
17. November 09 um 16:36 Uhr
Ein einfaches Beispiel mit C++11: ideone.com/lTsc7M
– Jarod42
4. Februar 14 um 16:24 Uhr