C++双重调度问题

发布于 2024-10-11 12:38:29 字数 1677 浏览 7 评论 0原文

这是我之前问过的问题的第二部分: Is C++ 中可能有多态成员重载吗?

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

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

#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

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

This is part 2 to a problem I previously asked: Is it possible to have polymorphic member overloading in C++?

Using the Wiki example I created this example.
http://en.wikipedia.org/wiki/Double_dispatch

My problem is that the compiled code never looks up the vtable, and always uses the base instead of the inherited class. Here is my code:

#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;
}

However, the output is always:

Vehicle Bump MapObject

Any help on this mystery is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黯淡〆 2024-10-18 12:38:29

您只进行了单次调度,没有进行两次调度。这个想法是,在 xVehicle 中,采用 xMapObject&,您将调用 ref.bump(*this);,其中是< /em> 双重调度。

You only did single dispatch, not double dispatch. The idea is that in xVehicle, taking an xMapObject&, you would call ref.bump(*this); which is double dispatch.

疯到世界奔溃 2024-10-18 12:38:29

它正在使用vtable;这就是为什么它调用 xVechicle::Bump()! vtable 不用于参数,这是没有意义的(至少在 C++ 中)。

典型的解决方案是让 Bump(xMapObject& obj) 调用 obj.Bump(*this);

It is using the vtable; that's why it's calling xVechicle::Bump()! The vtable isn't used on arguments, that doesn't make sense (in C++, at least).

The typical solution is to have e.g. Bump(xMapObject& obj) call obj.Bump(*this);.

回眸一遍 2024-10-18 12:38:29

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

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

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

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

Is a bad design the xEntity::Bump(xVehicle&) because you are using as parameter in a base class a derived class.

and at least that your contract change, you don't need redefine base Bump methods.

the problem is that you are creating the xMapRef vars, that convert your derived class to a base class.

if you want that appropriated method is called, just call with the derived class object

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文