开发者

Casting to derived type problem in C++

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_casts (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];
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜