Как да получа достъп до потребителски тип, след като бъде предаден на друг обект?

Нов съм в C++, така че ме извинете, ако не използвам терминология.

Пиша приложение в openframeworks, което използва библиотека по физика, наречена ofxMSAPhysics. За моите цели създадох персонализиран клас, наречен "particle", който наследява класа Particle3D на MSAPhysics.

Тук подавам указател към моя персонализиран обект към физическия двигател:

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. Току-що накарах моя заменен метод да настроя collide на true, за да видя дали работи.


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)


ако сте сигурни, че всички частици в системата са от вашия overiden тип, тогава можете просто да прехвърлите 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-style cast тук. Използвайте 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