1

根据 WikipediaMultiple Dispatch

...可以根据多个参数的运行时(动态)类型动态分派函数或方法。

但是,在 C++ 中,我可以覆盖派生类中的函数:

#include <iostream>

using namespace std;

class Base
{
public:
    virtual void method(int a) { cout << a; }
    virtual void method(int a, int b) { cout << a + b; }
};

class Derived: public Base
{
    void method(int a) { cout << a * 10 << endl; }
    void method(int a, int b) { cout << (a + b) * 10 <<endl; }
};

int main()
{
    Base* derived = new Derived;
    derived->method(1);
    derived->method(1, 2);
    return 0;
}

这里method是在运行时绑定的(因为我正在使用virtual),并且根据输入参数选择特定的方法——这与维基百科对多调度的描述有什么不同?

第二个问题:如果 C++ 中存在这种多态性和方法重载的组合,那么支持多分派的语言有什么优势(如果有的话)?

4

4 回答 4

4

它在运行时仅根据一个参数绑定,即调用它的对象。虚函数根据调用它们的对象的(动态)类型提供单一调度。

基于其他参数的数量和(静态)类型的重载选择是在编译时进行的。

于 2014-02-05T15:18:52.427 回答
3

不会。编译器根据接收者的静态类型和参数静态选择候选者。然后,在运行时,仅使用接收器的动态类型将调用绑定到最具体的覆盖方法。参数的动态类型在动态绑定阶段不起作用。

在您的特定情况下,这意味着对于 call derived->method(1);,编译器会查看接收者 ( Base) 和实际参数 ( int) 的静态类型。Base然后它在(继承的或声明的)的所有方法中搜索Base最匹配的方法;这是Base::method(int)。在运行时,运行时系统查看接收者的动态类型 ( Derived) 以寻找最具体的重写方法Base::method(int),即Derived::method(int),并使用给定的实际参数 ( ) 调用该方法1

第二次通话也是如此。

于 2014-02-05T15:22:20.933 回答
1

这不是多重分派,因为运行时选择仅基于一个参数完成:“派生”对象的类型。函数重载决议在编译时处理。

于 2014-02-05T15:19:07.170 回答
1
virtual void Base::method(int a);

可以看作

/*virtual*/ void method(Base&, int a);

所以,在你的情况下,你有

derived->method(1);将在以下之间发送:

/*virtual*/ void method(Base&, int a);
/*virtual*/ void method(Derived&, int a);

并将derived->method(1, 2);在以下之间发送:

/*virtual*/ void method(Base&, int a, int b);
/*virtual*/ void method(Derived&, int a, int b);

在这两种情况下,都只根据一个参数进行调度。

void method2(Base&, Base&);
void method2(Derived&, Base&);
void method2(Base&, Derived&);
void method2(Derived&, Derived&);

如果您想要 (with Base* derived = new Derived) method2(*derived, *derived);调用void method2(Derived&, Derived&); ,那么它需要多次调度。
(目前,它调用void method2(Base&, Base&);)。

于 2014-02-05T15:40:08.543 回答