Как получить доступ к пользовательскому типу после его передачи другому объекту?

Я новичок в C++, поэтому извините, если я не использую терминологию.

Я пишу приложение в openframeworks, которое использует физическую библиотеку под названием ofxMSAPhysics. Для своих целей я создал собственный класс под названием «particle», который наследуется от класса MSAPhysics Particle3D.

Здесь я передаю указатель на свой пользовательский объект физическому движку:

particle * p = new particle(ofVec3f(getTokenCoors(index)));
physics.addParticle(p);

В моем пользовательском классе у меня есть общедоступный член, называемый collide, который я устанавливаю в true, когда одна частица сталкивается с другой. Для этого я переопределяю один из виртуальных методов Particle3D:

void collidedWithParticle(ParticleT *other, ofVec3f collisionForce) {
        collide = true;
    }

Теперь я хотел бы проверить, когда одна частица сталкивается с другой. physics.getParticle(i) возвращает частицу из физического движка, но одного типа Particle3D, а не моего пользовательского типа частиц. Поэтому, когда я перебираю частицы, возвращенные из getParticle(), ни одна из них не содержит моей переменной "collide".

Есть ли способ получить доступ к моим пользовательским частицам после их добавления в движок?

Пожалуйста, дайте мне знать, если я могу что-то прояснить.

РЕДАКТИРОВАТЬ: collidedWithParticle() является виртуальным членом Particle3D. Я только что установил, что мой переопределенный метод сталкивается с истинным, чтобы увидеть, работает ли он.


person Miles    schedule 23.07.2013    source источник
comment
Какой интерфейс у Particle3D?   -  person greatwolf    schedule 23.07.2013
comment
Является ли collidedWithParticle виртуальной функцией-членом Particle3D или она специфична для particle?   -  person juanchopanza    schedule 23.07.2013
comment
@juanchopanza, судя по тому, как он сформулировал свой вопрос, похоже, первое. Но то, как назван метод, заставляет меня думать, что он должен возвращать bool, возможно?   -  person greatwolf    schedule 23.07.2013
comment
@juanchopanza Да, первое. Смотрите мою правку.   -  person Miles    schedule 23.07.2013


Ответы (2)


если вы уверены, что все частицы в системе имеют тип вашего переопределения, вы можете просто преобразовать Particle3D в particle, используя

particle* myParticle = static_cast<particle*>(other);

но этот способ не самый безопасный, я бы посоветовал вам, если возможно, проверить, возможно, есть какие-то методы, которые вы могли бы переопределить в классе Particle3D, которые позволили бы вам увидеть, столкнулись ли частицы или сохранить список ваших частиц и используйте этот список, чтобы убедиться, какие частицы относятся к унаследованному вами типу.
Конечно, dynamic_cast было бы более подходящим и более безопасным, но я не предлагаю использовать его из-за RTTI, так как RTTI сильно замедляет выполнение кода вниз.

person Opsenas    schedule 23.07.2013
comment
Что вам нужно, так это dynamic_cast<particle*>(other). - person juanchopanza; 23.07.2013
comment
Ах. Я задавался вопросом, смогу ли я привести его, но я забыл идентификатор указателя (*) в (particle*). Красиво получилось - спасибо! - person Miles; 23.07.2013
comment
Вам действительно не следует использовать приведение C-стиля здесь. Используйте dynamic_cast, как было предложено juanchopanza для правильного полиморфного поведения. Если other на самом деле не particle*, то dynamic_cast вернет null. - person greatwolf; 23.07.2013
comment
dynamic_cast требует RTTI, который сильно замедляет выполнение кода, поэтому я предлагаю cstyle cast или static... - person Opsenas; 23.07.2013
comment
Итак, вы бы предпочли использовать какой-то код, который может просто делать неправильные вещи только потому, что он может работать медленнее, чем правильный код? - person juanchopanza; 23.07.2013
comment
@juanchopanza читал о недостатках RTTI, и, как я уже упоминал в своем ответе, это не лучший вариант, на мой взгляд... - person Opsenas; 23.07.2013
comment
Мне не нужно ничего читать о RTTI, спасибо. Но вы должны прочитать о том, как плохо static_cast может пойти здесь. - person juanchopanza; 23.07.2013

Когда вы просматриваете свои частицы, вам нужно, чтобы все объекты были приведены к базовому классу. Технически у вас может быть такой массив:

std::vector <Particle3D*> particles;

Поскольку ваша собственная частица унаследована от этого класса, вы можете сделать следующее:

particle* yourParticle = new particle();
particles.push_back(yourParticle);

Вам разрешено это делать, потому что yourParticle — это класс, базовым классом которого является Particle3D. Это лишь одна из многих особенностей объектно-ориентированного программирования.

person Joseph Pla    schedule 23.07.2013