2

这是我之前问过的一个问题的第 2 部分:是否可以在 C++ 中进行多态成员重载?

使用 Wiki 示例我创建了这个示例。 http://en.wikipedia.org/wiki/Double_dispatch

我的问题是编译后的代码从不查找 vtable,并且总是使用基类而不是继承类。这是我的代码:

#include <iostream>

class xEntity;
class xVehicle;

class xMapObject
{
  public:
    virtual void Bump(xMapObject&) { std::cout << "MapObject Bump MapObject\n"; };
    virtual void Bump(xEntity&) { std::cout << "MapObject Bump Entity\n"; };
    virtual void Bump(xVehicle&) { std::cout << "MapObject Bump Vehicle\n"; };
};

class xEntity : public xMapObject
{
  public:
    virtual void Bump(xMapObject&) { std::cout << "Entity Bump MapObject\n"; };
    virtual void Bump(xEntity&) { std::cout << "Entity Bump Entity\n"; };
    virtual void Bump(xVehicle&) { std::cout << "Entity Bump Vehicle\n"; };
};

class xVehicle : public xEntity
{
  public:
    virtual void Bump(xMapObject&) { std::cout << "Vehicle Bump MapObject\n"; };
    virtual void Bump(xEntity&) { std::cout << "Vehicle Bump Entity\n"; };
    virtual void Bump(xVehicle&) { std::cout << "Vehicle Bump Vehicle\n"; };
};

int main(int argv, char **argc)
{
    xEntity Entity;
    xVehicle Vechile;

    xMapObject &EntityRef = Entity;
    xMapObject &VehicleRef = Vechile;

    VehicleRef.Bump(EntityRef);

    return 0;
}

但是,输出始终是:

Vehicle Bump MapObject

非常感谢您对这个谜团的任何帮助。

4

3 回答 3

6

您只进行了一次调度,而不是两次调度。这个想法是,在xVehicle, 中xMapObject&,你会调用ref.bump(*this);双重调度。

于 2011-01-12T16:56:53.453 回答
1

它正在使用 vtable;这就是它打电话的原因xVechicle::Bump()!vtable 不用于参数,这没有意义(至少在 C++ 中)。

典型的解决方案是让例如Bump(xMapObject& obj)call obj.Bump(*this);

于 2011-01-12T17:00:08.677 回答
1

xEntity::Bump(xVehicle&) 是一个糟糕的设计,因为您在派生类的基类中用作参数。

并且至少您的合同发生了变化,您不需要重新定义基本Bump方法。

问题是您正在创建xMapRef变量,它将您的派生类转换为基类。

如果您希望调用该适当的方法,只需使用派生类对象调用

于 2011-01-12T17:41:03.640 回答