【问题标题】:Multiple dispatch and multi-methods多调度多方法
【发布时间】:2010-12-02 21:07:02
【问题描述】:

它们是什么,它们之间有什么不同?

许多消息来源,如Wikipedia,声称它们是同一件事,但其他人明确表示相反,如this question中的sbi:

首先:“访问者模式是一种在 C++ 中模拟双重调度的方法。”这是,呃,不完全正确。实际上,双重分派是多重分派的一种形式,是在 C++ 中模拟(缺失的)多重方法的一种方式。

【问题讨论】:

    标签: oop multiple-dispatch double-dispatch multimethod


    【解决方案1】:

    它们是一样的。

    当您在 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 a Dervied*”。 (遗憾的是,C++ 没有多重调度,因此程序会打印出“Called Derived::Foo with a Base*”。)

    Double-dispatch 是 Multiple-dispatch 的一种特殊情况,通常更容易模拟,但作为一种语言功能并不十分常见。大多数语言要么进行单次调度,要么进行多次调度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-20
      • 1970-01-01
      • 2021-02-06
      • 2021-06-17
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多