Ugrás a tartalomhoz

double dispatch

A Wikiszótárból, a nyitott szótárból


Főnév

double dispatch (tsz. double dispatches)

  1. (informatika) Double dispatch egy programozási technika, amely akkor jön létre, amikor a végső viselkedés kiválasztása két objektum típusától függ – nem csak egytől, mint az egyszerű virtuális függvényhívásoknál (azaz single dispatch-nél).



🧠 Mi az a Double Dispatch?

A double dispatch lehetővé teszi, hogy egy függvény viselkedése két objektum tényleges futásidejű típusától függjön – például amikor két különböző típusú objektum interakcióba lép, és az eredményt az egymás típusa szerint különbözően kell kezelni.

Ez gyakori például:

  • játékmotorokban (pl. egy “Goblin” ütközik egy “Player”-rel)
  • matematikai kifejezések kiértékelésénél
  • Visitor design pattern használatakor



👀 Single vs. Double Dispatch

Típus Mitől függ a kiválasztott függvény?
Single dispatch Az objektum egyik típusától (pl. this)
Double dispatch Az objektum két típusától (pl. this és other)



🧱 C++ példával

Tegyük fel, hogy van egy játék, ahol két típusú karakter csatázhat: Warrior és Mage. Azt szeretnénk, hogy külön logika legyen attól függően, ki támad meg kit.

#include <iostream>
using namespace std;

class Character;

class Warrior;
class Mage;

// Bázisosztály
class Character {
public:
    virtual void attack(Character& target) = 0;
    virtual void beAttackedBy(Warrior& attacker) = 0;
    virtual void beAttackedBy(Mage& attacker) = 0;
    virtual ~Character() = default;
};

// Harcos
class Warrior : public Character {
public:
    void attack(Character& target) override {
        target.beAttackedBy(*this);  // double dispatch: target + attacker típus
    }

    void beAttackedBy(Warrior& attacker) override {
        cout << "Warrior vs Warrior: shield clash!" << endl;
    }

    void beAttackedBy(Mage& attacker) override {
        cout << "Mage zaps Warrior!" << endl;
    }
};

// Mágus
class Mage : public Character {
public:
    void attack(Character& target) override {
        target.beAttackedBy(*this);  // double dispatch itt is
    }

    void beAttackedBy(Warrior& attacker) override {
        cout << "Warrior slashes Mage!" << endl;
    }

    void beAttackedBy(Mage& attacker) override {
        cout << "Mage duel begins!" << endl;
    }
};

Használat:

int main() {
    Warrior w;
    Mage m;

    w.attack(m);  // Warrior slashes Mage!
    m.attack(w);  // Mage zaps Warrior!
    w.attack(w);  // Warrior vs Warrior: shield clash!
}

🧰 Mi történik itt?

  1. w.attack(m) hívásnál:
    • Először Warrior::attack fut le (single dispatch)
    • Az m.beAttackedBy(w) hívásnál most m (Mage) típusa dönt: ez a második dispatch

Eredmény: a viselkedés a Warrior + Mage típuspárostól függ.



📦 Mikor hasznos?

  • Több öröklési ágban kell kombinációkat kezelni
  • Játékoknál (pl. ütés, varázslás, összeütközés)
  • Interpreterekben (pl. AST node-ok egymásba ágyazva)
  • Kifejezések értelmezésénél
  • Visitor pattern implementálásánál



🧠 TL;DR

  • Double dispatch = A függvénykiválasztás két objektum típusától függ.
  • C++-ban nem natív, de megvalósítható virtuális függvények láncolásával.
  • Hasznos, amikor típus kombinációktól függ a logika.