它们是什么,它们之间有什么不同?
许多来源,例如Wikipedia,声称它们是相同的,但其他人明确地说相反,例如this question中的 sbi :
首先:“访问者模式是一种在C ++中模拟Double Dispatching的方法。”这是,呃,不完全正确。实际上,双重调度是多重调度的一种形式,这是一种在C ++中模拟(缺失)多方法的方法。
答案 0 :(得分:5)
他们是一样的。
在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 ++有多个调度,程序将打印出“使用Dervied *调用Derived :: Foo”。 (遗憾的是,C ++没有多个调度,所以程序打印出“Called Derived :: Foo with a Base *”。)
Double-dispatch是多分派的一种特殊情况,通常更容易模拟,但作为语言功能并不常见。大多数语言都是单发或多发。