派生类与多重调度中的重载方法

时间:2014-02-05 15:13:00

标签: c++ overloading multiple-dispatch

According to Wikipedia多个调度

  

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

但是,在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 个答案:

答案 0 :(得分:4)

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

在编译时根据其他参数的数量和(静态)类型选择重载。

答案 1 :(得分:3)

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

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

同样适用于第二次通话。

答案 2 :(得分:1)

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

答案 3 :(得分: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&);

如果您想要(使用Base* derived = new Derivedmethod2(*derived, *derived);来电void method2(Derived&, Derived&); 那么它需要多次派遣 (目前,它调用void method2(Base&, Base&);)。