Проблема C ++, касающаяся наследования и приведения - PullRequest
1 голос
/ 01 марта 2011

В настоящее время я работаю над физическим движком-любителем для школьного проекта, но застрял из-за проблемы C ++.Настройки следующие:

У меня есть три разных класса:

  • RigidBody (аннотация)
  • Сфера (наследуется от RigidBody)
  • CustomRigidBody(наследует от RigidBody и представляет многогранник)

Мне нужно проверить, не происходит ли столкновение между парой тел двумя одноименными методами.Один используется для проверки контакта со сферой, тогда как другой используется для проверки контакта с CustomRigidBody.Существует несколько возможных сценариев (столкновение «Сфера / сфера», столкновение «сфера / пользовательский» и т. Д.), Поэтому эти два метода определены во всех этих классах.

В RigidBody они абстрактны:

virtual bool isCollidingWith(Sphere* s_p) = 0;
virtual bool isCollidingWith(CustomRigidBody* rb_p) = 0;

Но не в сфере:

bool isCollidingWith(Sphere* s_p);
bool isCollidingWith(CustomRigidBody* rb_p);

Ни в CustomRigidBody:

bool isCollidingWith(Sphere* s_p);
bool isCollidingWith(CustomRigidBody* rb_p);

В моей основной программе у меня есть std::vector<RigidBody*>, содержащий указатели на RigidBodies (суперкласс) и мне нужно проверить наличие коллизий между объектами по паре, вызвав что-то вроде:

for(int i = 1; i < this->bodies_p.size(); ++i)
    for(int j = 0; j < i; ++j)
        if(this->bodies_p[i]->isCollidingWith(this->bodies_p[j]))
            std::cout << " COLLISION BETWEEN " << i << " AND " << j << std::endl;

У меня сложилось впечатление, что C ++ будет в порядке с этим, но я получаю следующее сообщение об ошибке:

Engine.cc:35: error: no matching function for call to ‘RigidBody::isCollidingWith(RigidBody*&)’
RigidBody.h:53: note: candidates are: virtual bool RigidBody::isCollidingWith(Sphere*)
RigidBody.h:54: note:                 virtual bool        RigidBody::isCollidingWith(CustomRigidBody*)

Я предполагаю, что это связано с тем, что вектор тел содержит указатели на RigidBodies, и они не автоматически приводятся к Sphere * или CustomRigidBody *, но я не знаю, как решить проблему.

Спасибо за вашу помощь;)

1 Ответ

4 голосов
/ 01 марта 2011

Эта проблема решается с помощью Двойная отправка .По сути, вам нужно добавить еще одну перегрузку к RigidBody и его производным классам:

bool isCollidingWith(RigidBody* rb_p) = 0;

В производных классах, например, Sphere, реализация будет выглядеть следующим образом:

bool Sphere::isCollidingWith(RigidBody* rb_p)
{
    return rb_p->isCollidingWith(this);
}

Это работает, потому что при первом вызове isCollidingWith (в вашем цикле) вызывается версия isCollidingWith(RigidBody*) из правильного производного класса (через виртуальный метод).Затем в Sphere::isCollidingWith(RigidBody*) правильный производный класс используется через виртуальный метод.Однако на этот раз this представляет собой Sphere*, поэтому вызываемая перегрузка имеет версию isCollidingWith(Sphere*).

Другими словами:

  1. InВаш цикл:

    this->bodies_p[i]->isCollidingWith(this->bodies_p[j])
    

    будет вызывать Sphere::isCollidingWith(RigidBody*) или CustomRigidBody::isCollidingWith(RigidBody*), в зависимости от фактического типа bodies_p[i].Если предположить, что это Sphere, то мы получим

  2. In Sphere::isCollidingWith(RigidBody* rb_p):

    return rb_p->isCollidingWith(this);
    

    , который вызывает либо Sphere::isCollidingWith(Sphere*), либо CustomRigidBody::isCollidingWith(Sphere*), в зависимости отфактический тип rb_p.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...