C++双重调度问题
这是我之前问过的问题的第二部分: 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您只进行了单次调度,没有进行两次调度。这个想法是,在
xVehicle
中,采用xMapObject&
,您将调用ref.bump(*this);
,其中是< /em> 双重调度。You only did single dispatch, not double dispatch. The idea is that in
xVehicle
, taking anxMapObject&
, you would callref.bump(*this);
which is double dispatch.它正在使用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)
callobj.Bump(*this);
.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