Многократная отправка и многократные методы - PullRequest
0 голосов
/ 03 декабря 2010

Кто они, чем они отличаются?

Многие источники, такие как Википедия , утверждают, что они одно и то же, но другие прямо говорят об обратном, например sbi в этот вопрос :

Первое: «Шаблон посетителя - это способ симуляции двойной диспетчеризации в C ++». Это не совсем верно. На самом деле, двойная диспетчеризация - это одна из форм множественной диспетчеризации, которая является способом моделирования (отсутствующих) мульти-методов в C ++.

1 Ответ

5 голосов
/ 03 декабря 2010

Они одинаковы.

Когда вы вызываете виртуальный метод в C ++, фактический метод, который нужно запустить, основан на типе времени выполнения объекта, для которого вызывается их метод.Это называется «одиночной отправкой», потому что это зависит от типа одного аргумента (в данном случае, неявного аргумента «this»).Так, например, следующее:

class Base {
  public:
    virtual int Foo() { return 3; }
}

class Derived : public Base {
  public:
    virtual int Foo() { return 123; }
}

int main(int argc, char *argv[]) {
  Base* base = new Derived;
  cout << "The result is " << base->Foo();
  delete base;
  return 0;
}

При запуске вышеприведенная программа печатает 123, а не 3. Пока все хорошо.

Многократная диспетчеризация - это способность языка иливремя выполнения для отправки как по типу указателя 'this' , так и по типу аргументов метода.Рассмотрим (придерживаясь синтаксиса C ++ на данный момент):

class Derived;

class Base {
  public:
    virtual int Foo(Base *b) { cout << "Called Base::Foo with a Base*"; }
    virtual int Foo(Derived *d) { cout << "Called Base::Foo with a Derived*"; }
}

class Derived : public Base {
  public:
    virtual int Foo(Base *b) { cout << "Called Derived::Foo with a Base*"; }
    virtual int Foo(Derived *d) { cout << "Called Derived::Foo with a Derived*"; }
}

int main(int argc, char *argv[]) {
  Base* base = new Derived;
  Base* arg = new Derived;

  base->Foo(arg);

  delete base;
  delete arg;
  return 0;
}

Если бы C ++ имел многократную диспетчеризацию, программа выдала бы «Called Derived :: Foo with Dervied *».(К сожалению, C ++ не поддерживает множественную диспетчеризацию, поэтому программа выводит «Called Derived :: Foo with the Base *».)

Двойная диспетчеризация - это особый случай множественной диспетчеризации, часто прощеподражать, но не очень часто в качестве языковой функции.Большинство языков делают одну или несколько отправок.

...