C ++ Double Dispatch проблемы - PullRequest
       21

C ++ Double Dispatch проблемы

2 голосов
/ 12 января 2011

Это часть 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

Любая помощь в этой тайне очень ценится.

Ответы [ 3 ]

6 голосов
/ 12 января 2011

Вы сделали только одну отправку, а не двойную.Идея состоит в том, что в xVehicle, взяв xMapObject&, вы бы назвали ref.bump(*this);, что равно двойной отправке.

1 голос
/ 12 января 2011

Плохой дизайн xEntity :: Bump (xVehicle &), потому что вы используете в качестве параметра в базовом классе производный класс.

и, по крайней мере, если ваш контракт меняется, вам не нужно переопределять базовые методы Bump .

проблема в том, что вы создаете xMapRef переменные, которые преобразуют ваш производный класс в базовый класс.

если вы хотите, чтобы этот присвоенный метод вызывался, просто вызовите объект производного класса

1 голос
/ 12 января 2011

Это использует vtable; вот почему он звонит xVechicle::Bump()! Vtable не используется для аргументов, это не имеет смысла (по крайней мере, в C ++).

Типичное решение - например, Bump(xMapObject& obj) Звоните obj.Bump(*this);.

...