I am quite new to C++, but have worked with C# for years, however it is not helping me here! :)
My problem: I have an Actor
class which Ball
and Peg
both derive from on an objective-c iphone game I am working on. As I am testing for collision, I wish to set an instance of Ball
and Peg
appropriately depending on the actual runtime type of actorA
or actorB
. My code that tests this as follows:
// Actors that collided
Actor *actorA = (Actor*) bodyA->GetUserData();
Actor *actorB = (Actor*) bodyB->GetUserData();
Ball* ball;
Peg* peg;
if (static_cast<Ball*> (actorA)) { // true
ball = static_cast<Ball*> (actorA);
}
else if (static_cast<Ball*> (actorB)) {
ball = static_cast<Ball*> (actorB);
}
if (static_cast<Peg*> (actorA)) { // also true?!
peg = static_cast<Peg*> (actorA);
}
else if (static_cast<Peg*> (actorB)) {
peg = static_cast<Peg*> (actorB);
}
if (peg != NULL) {
[peg hitByBall];
}
Once ball
and peg
are set, I then proceed to run the hitByBall
method (objective c).
Where my problem really lies is in the casting procedurel Ball
casts fine from actorA
; the first if (static_cast<>)
statement steps in and sets the ball
pointer appropriately.
The second step is to assign the appropriate type to peg
. I know peg
should be a Peg
type and I previously know it will be actorB
, however at runtime, detecting the types, I was surprised to find actually the th开发者_运维知识库ird if (static_cast<>)
statement stepped in and set this, this if statement was to check if actorA
was a Peg
, which we already know actorA
is a Ball
! Why would it have stepped here and not in the fourth if
statement?
The only thing I can assume is how casting works differently from c# and that is it finds that actorA
which is actually of type Ball
derives from Actor
and then it found when static_cast<Peg*> (actorA)
is performed it found Peg
derives from Actor
too, so this is a valid test? This could all come down to how I have misunderstood the use of static_cast
. How can I achieve what I need? :)
I'm really uneasy about what feels to me like a long winded brute-casting attempt here with a ton of ridiculous if
statements. I'm sure there is a more elegant way to achieve a simple cast to Peg
and cast to Ball
dependent on actual type held in actorA
and actorB
.
Hope someone out there can help! :) Thanks a lot.
Since this is Objective-C code (not C++, as per the title), why not just call:
[actorA hitByBall];
[actorB hitByBall];
Updated: If the object you are sending the message to is nil
it will be ignored. If the object you send the message to does not implement hitByBall
, you'll get an exception, "selector not recognized", unless you have put an empty definition in your base class (Actor
).
You can then remove your ball
and peg
declarations and all of the static_cast
s (which would have been incorrect even in C++).
To identify object type at run time you should dynamic_cast
and not static_cast
. But you should really reconsider your design. Probably (I don't anything about objective-c) you should make hitByBall
a virtual method in base class and override the implementation if required in derived classes. Then you can call the method without any casts.
It seems you are looking for -isKindOfClass
. If both objects conform to the NSObject protocol, you only need to check which is of which type - the actual message passing is not limited by the static type of the pointer:
if ( [actorA isKindOfClass:[Peg class ]]
&& [actorB isKindOfClass:[Ball class]])
{
[actorA hitByBall];
}
else if ( [actorB isKindOfClass:[Peg class ]]
&& [actorA isKindOfClass:[Ball class]])
{
[actorB hitByBall];
}
精彩评论