Несколько диспетчеризируют в C++

GateKiller, как насчет того, чтобы добавить break к тому if в foreach цикл? Это ускорило бы вещи много , потому что, если как 6 является делимым 2, Вы не должны сверяться 3 и 5. (Я проголосовал бы за Ваше решение так или иначе, если бы у меня было достаточно репутации:-)...)

ArrayList primeNumbers = new ArrayList();

for(int i = 2; primeNumbers.Count < 10000; i++) {
    bool divisible = false;

    foreach(int number in primeNumbers) {
        if(i % number == 0) {
            divisible = true;
            break;
        }
    }

    if(divisible == false) {
        primeNumbers.Add(i);
        Console.Write(i + " ");
    }
}

36
задан Shog9 7 August 2010 в 16:04
поделиться

4 ответа

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

Вот пример, который не работает прямо в C ++ (непроверено):

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);
65
ответ дан 27 November 2019 в 05:22
поделиться

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

В C ++ есть одиночная отправка, потому что когда вы используете виртуальные функции, фактическая функция, которая запускается, зависит только от типа времени выполнения объекта слева от -> или. оператор.

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

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.

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

20
ответ дан 27 November 2019 в 05:22
поделиться

См. Этот документ, написанный Б. Страуструпом: Открытые мульти-методы для C ++

11
ответ дан 27 November 2019 в 05:22
поделиться

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

В следующем примере функция 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*/ }
};

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

3
ответ дан 27 November 2019 в 05:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: