Я пытаюсь понять, что такое множественная отправка. Я читал много разных текстов, но я до сих пор не знаю, что такое многократная отправка и для чего это хорошо. Может быть, вещь, которую мне не хватает, - это часть кода, использующая множественную отправку. Пожалуйста, напишите небольшой кусок кода на С++, используя несколько диспетчеров, чтобы я мог видеть, что он не может быть скомпилирован/правильно запущен, потому что С++ имеет только одну отправку? Мне нужно увидеть разницу. Спасибо.
Несколько отправки в С++
Ответ 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.
Что делает функция, зависит от типов обоих аргументов, а не только от одного. В С++ вам, возможно, придется писать это как некоторые виртуальные функции. В зависимости от одного аргумента (этого указателя) будет выбрана виртуальная функция. Тогда виртуальной функции может потребоваться содержать переключатель или что-то, что бы сделать что-то особенное для другого аргумента.
Ответ 3
См. эту статью, написанную Б. Страуступом: Открыть Multi-Методы для С++
Ответ 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*/ }
};
Пример основан на этой статье.