2011-01-12 2 views
2

Cela fait partie 2 à un problème que j'ai déjà posée: Is it possible to have polymorphic member overloading in C++?C++ problèmes Double Dispatch

En utilisant l'exemple Wiki j'ai créé cet exemple. Mon problème est que le code compilé ne recherche jamais le vtable, et utilise toujours la base au lieu de la classe héritée. Voici mon 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; 
} 

Cependant, la sortie est toujours:

Vehicle Bump MapObject 

Toute aide sur ce mystère est très apprécié.

Répondre

6

Vous avez fait une seule expédition, pas une double expédition. L'idée est que dans xVehicle, prenant un xMapObject&, vous appelleriez ref.bump(*this); dont est double expédition.

+0

Cela fait beaucoup de sens maintenant. Je vous remercie! –

+0

Si cela répond à votre question, vous devez la marquer comme acceptée. – Puppy

+0

Je devais attendre que la minuterie expire. –

1

Il utilise le vtable; Voilà pourquoi il appelle xVechicle::Bump()! Le vtable n'est pas utilisé sur les arguments, cela n'a pas de sens (en C++, au moins).

La solution typique consiste à avoir par ex. Bump(xMapObject& obj) appelez obj.Bump(*this);.

1

Une mauvaise conception est le xEntity :: Bump (xVéhicule &) car vous utilisez comme paramètre dans une classe de base une classe dérivée.

et au moins que votre contrat change, vous n'avez pas besoin de redéfinir la base Bump méthodes.

le problème est que vous créez les xMapRef vars, qui convertissent votre dérivée classe à une classe de base.

Si vous voulez que la méthode appropriée soit appelée, appelez simplement avec l'objet de classe dérivé

+0

C'était juste pour tester, en suivant l'exemple de Wiki. Il a été changé dans la version actuelle. –