Mehrfachversand in C++

Lesezeit: 5 Minuten

Mehrfachversand in C
Martin

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.

  • 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

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

1643907006 138 Mehrfachversand in C
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

.

757710cookie-checkMehrfachversand in C++

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy