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

Overloading method in derived class vs multiple dispatch

本文关键字:方法 调度 派生      更新时间:2023-10-16

根据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),并且根据输入参数选择了特定方法 - 这与Wikipedia的Wikipedia描述有何不同?

次要问题:如果在C ?

中存在这种多态性和方法过载的组合,那么支持多重调度的语言的优势(如果有)是什么优势(如果有)。

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

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