C++ Double Dispatch проблемы
Это вторая часть проблемы, которую я ранее задавал: возможно ли перегрузка полиморфного члена в 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
Любая помощь по этой тайне очень ценится.
3 ответа
Вы сделали только одну отправку, а не двойную отправку. Идея в том, что в xVehicle
взяв xMapObject&
позвонил бы ref.bump(*this);
которая является двойной отправкой.
Плохой дизайн xEntity::Bump(xVehicle&), потому что вы используете в качестве параметра в базовом классе производный класс.
и, по крайней мере, если ваш контракт изменился, вам не нужно переопределять базовые методы Bump.
проблема в том, что вы создаете переменные xMapRef, которые преобразуют ваш производный класс в базовый класс.
если вы хотите, чтобы был вызван соответствующий метод, просто вызовите объект производного класса
Он использует vtable; вот почему он звонит xVechicle::Bump()
! Vtable не используется для аргументов, это не имеет смысла (по крайней мере, в C++).
Типичным решением является, например, Bump(xMapObject& obj)
вызов obj.Bump(*this);
,