2

我对 C++ 很陌生,但已经使用 C# 多年,但它在这里对我没有帮助!:)

我的问题:我有一个Actor类,Ball它们Peg都来自我正在开发的objective-c iphone游戏。当我测试碰撞时,我希望根据or的实际运行时类型适当地设置Ball和的实例。我的测试代码如下:PegactorAactorB

// 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];
        }

一旦ballpeg被设置,然后我继续运行该hitByBall方法(目标 c)。

我的问题真正出在铸造过程中,BallactorA; 第一if (static_cast<>)条语句介入并ball适当地设置指针。

第二步是将适当的类型分配给peg. 我知道peg应该是一个Peg类型,我以前知道它会是actorB,但是在运行时,检测类型,我惊讶地发现实际上第三个if (static_cast<>)语句介入并设置了这个,这个 if 语句是为了检查是否actorA是一个Peg,我们已经知道actorA是一个Ball!为什么它会走到这里而不是在第四个if声明中?

我唯一可以假设的是强制转换与 c# 的工作方式有何不同,那就是它发现actorA实际上是类型Ball派生的Actor,然后它在 static_cast<Peg*> (actorA)执行时发现它也发现Peg派生自Actor,所以这是一个有效的测试?这一切都可能归结为我如何误解了static_cast. 我怎样才能达到我所需要的?:)

if我真的很不安,这让我感觉像是在这里用大量荒谬的陈述进行冗长的粗暴尝试。我确信有一种更优雅的方法可以实现简单的强制转换Peg和强制转换,Ball具体取决于保存在actorAand中的实际类型actorB

希望有人可以提供帮助!:) 非常感谢。

4

3 回答 3

3

由于这是 Objective-C 代码(不是 C++,根据标题),为什么不直接调用:

[actorA hitByBall];
[actorB hitByBall];

更新:如果您要发送消息的对象是nil它将被忽略。如果你发送消息的对象没有实现hitByBall,你会得到一个异常,“选择器无法识别”,除非你在你的基类(Actor)中放了一个空的定义。

然后,您可以删除您的ballandpeg声明和所有static_casts(即使在 C++ 中也是不正确的)。

于 2010-05-22T05:46:03.087 回答
2

要在运行时识别对象类型,您应该dynamic_cast和不应该static_cast. 但是你真的应该重新考虑你的设计。可能(我对objective-c一无所知)您应该hitByBall在基类中创建一个虚拟方法,并在派生类中需要时覆盖实现。然后,您可以在不进行任何强制转换的情况下调用该方法。

于 2010-05-22T04:16:33.863 回答
1

看来您正在寻找-isKindOfClass. 如果两个对象都符合 NSObject 协议,你只需要检查哪个是哪个类型 - 实际的消息传递不受指针静态类型的限制:

if (   [actorA isKindOfClass:[Peg class ]] 
    && [actorB isKindOfClass:[Ball class]]) 
{
    [actorA hitByBall];
}
else if (   [actorB isKindOfClass:[Peg class ]]
         && [actorA isKindOfClass:[Ball class]]) 
{
    [actorB hitByBall];
}
于 2010-05-22T06:07:52.080 回答