Подтвердить что ты не робот

Несколько отправки в С++

Я пытаюсь понять, что такое множественная отправка. Я читал много разных текстов, но я до сих пор не знаю, что такое многократная отправка и для чего это хорошо. Может быть, вещь, которую мне не хватает, - это часть кода, использующая множественную отправку. Пожалуйста, напишите небольшой кусок кода на С++, используя несколько диспетчеров, чтобы я мог видеть, что он не может быть скомпилирован/правильно запущен, потому что С++ имеет только одну отправку? Мне нужно увидеть разницу. Спасибо.

4b9b3361

Ответ 1

Multi-dispatch - это возможность выбрать, какую версию функции вызывать на основе типа времени выполнения аргументов, переданных вызову функции.

Вот пример, который не будет работать на С++ (непроверенный):

class A { };
class B : public A { };
class C : public A { }


class Foo
{
  virtual void MyFn(A* arg1, A* arg2) { printf("A,A\n"); }
  virtual void MyFn(B* arg1, B* arg2) { printf("B,B\n"); }
  virtual void MyFn(C* arg1, B* arg2) { printf("C,B\n"); }
  virtual void MyFn(B* arg1, C* arg2) { printf("B,C\n"); }
  virtual void MyFn(C* arg1, C* arg2) { printf("C,C\n"); }
};

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);

Ответ 2

Несколько отправлений - это когда выполняемая функция зависит от типа времени выполнения более чем одного объекта.

С++ имеет отдельную отправку, потому что, когда вы используете виртуальные функции, фактическая функция, которая запускается, зависит только от типа времени выполнения объекта слева от → или. Оператор.

Я пытаюсь думать о реальном случае программирования для множественной отправки. Возможно, в игре, где разные герои сражаются друг с другом.

void Fight(Opponent& opponent1, Opponent& opponent2);

Победитель боя может зависеть от характеристик обоих противников, поэтому вы можете захотеть, чтобы этот вызов отправил одно из следующих значений, в зависимости от типов выполнения обоих аргументов:

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.

Что делает функция, зависит от типов обоих аргументов, а не только от одного. В С++ вам, возможно, придется писать это как некоторые виртуальные функции. В зависимости от одного аргумента (этого указателя) будет выбрана виртуальная функция. Тогда виртуальной функции может потребоваться содержать переключатель или что-то, что бы сделать что-то особенное для другого аргумента.

Ответ 4

При отдельной отправке выполняемая функция зависит только от типа объекта. В двойная отправка выполняемой функции зависит от типа объекта и параметр.

В следующем примере функция Area() вызывается с использованием единая отправка и Intersect() зависит от двойной отправки, потому что требуется Параметр формы.

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*/ }
};

Пример основан на этой статье.