2011-07-04 4 views
1

Вот моя проблема.Помогите с проблемой дизайна

Я использую библиотеку физики под названием Box2D. Я могу подключить слушателя, который скажет мне, когда сталкиваются 2 светильника.

По существу, Box2D работает, создавая b2Bodies. Поэтому я знаю только, к какому b2Body принадлежит столкновение. В моей игре у меня есть Entity, и из этого у меня есть PhisicsEntity. Функция PhysicalEntity содержит указатель на b2Body. Он также имеет метод sendMessage, который поступает от Entity. Проблема в том, что из b2Body, как отправить сообщение «Идентификация состояния» сообщение о столкновении. То, что я подумал о том, чтобы установить userData void * из b2Body в его соответствующую PhysicsEntity. Кажется очень неправильным, что нужно сделать void *, чтобы сделать это.

Есть ли лучший способ, с помощью которого я мог бы очень быстро узнать физическую сущность, связанную с b2Body без кастинга или поиска?

Благодаря

ответ

0

Это как раз та цель, в которой поля, подобные этому полю userData, предназначены для - ссылки на данные вашего приложения, связанные с объектом библиотеки. Это полностью подходящее использование void *.

Если бы вы спрашивали о C, я бы сказал, что вам также не нужно использовать какие-либо приведения, так как преобразование в и из void * может быть выполнено без каких-либо бросков и необходимость использования приведения является признаком возможной проблемы , но если я правильно напомню, что на C++ требуются эти приведения (я не уверен, что C++ достаточно).

+0

C++ требует отбрасывания до и от void *. В частности, это помогает людям использовать void * как «указатель на что-то» или как дешевый литой от одного типа к другому, что может вызвать разлом при множественном наследовании. – dascandy

0

что на самом деле именно то, что указатель USERDATA предназначен для. Это довольно стандартная парадигма - посмотрите на такие функции, как pthread_create или CreateThread, для другого примера.

Если вы столкнулись с библиотекой, которая не позволяет вам использовать void * (или не безопасно - например, хранить его локально как int), вы можете использовать std :: map для разрешения типа. Это медленнее и с гораздо большим количеством накладных расходов.

+0

Поскольку класс является полиморфным, должен ли я динамический литье? – jmasterx

+0

Нет, вы можете использовать static_cast или c-style case (предпочитаете бывшее, хотя). Вы бросаете его только здесь и из одного и того же типа указателя, чтобы все было в порядке. Reinterpret_cast даже работал бы - но это не обязательно и было бы признаком чего-то уродливого, что это не так (по крайней мере, не так много). – dascandy

Смежные вопросы