C+中派生型问题的转换+; 我对C++很陌生,但多年来一直与C语言合作,但是它在这里没有帮助我!p>
我的问题是:我有一个C+中派生型问题的转换+; 我对C++很陌生,但多年来一直与C语言合作,但是它在这里没有帮助我!p>,c++,objective-c,casting,box2d-iphone,C++,Objective C,Casting,Box2d Iphone,我的问题是:我有一个Actor类,它的Ball和Peg都源于我正在开发的objective-c iphone游戏。在测试碰撞时,我希望根据actorA或actorB的实际运行时类型,适当地设置Ball和Peg的实例。我的测试代码如下所示: // Actors that collided Actor *actorA = (Actor*) bodyA->GetUserData(); Actor *actorB = (Actor*) bodyB->GetUs
Actor
类,它的Ball
和Peg
都源于我正在开发的objective-c iphone游戏。在测试碰撞时,我希望根据actorA或actorB的实际运行时类型,适当地设置Ball
和Peg
的实例。我的测试代码如下所示:
// 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];
}
//冲突的参与者
Actor*actorA=(Actor*)bodyA->GetUserData();
Actor*actorB=(Actor*)bodyB->GetUserData();
球*球;
Peg*Peg;
if(static_cast(actorA)){//true
ball=静态施法(actorA);
}
否则如果(静态_转换(actorB)){
球=静态施法(actorB);
}
如果(static_cast(actorA)){//也是真的?!
peg=静态铸件(actorA);
}
否则如果(静态_转换(actorB)){
peg=静态铸件(actorB);
}
if(peg!=NULL){
[peg Hitbybyl];
}
一旦设置了ball
和peg
,我就开始运行hitbybyball
方法(目标c)
我真正的问题在于铸造过程。Ball
从actorA
铸造的球很好;第一个if(static_cast)
语句步进并适当设置ball
指针
第二步是将适当的类型分配给peg
。我知道peg
应该是peg
类型,我以前知道它将是actorB
,但是在运行时,检测到这些类型,我惊讶地发现实际上第三个if(static_cast)
语句介入并设置了这个,这个if语句是为了检查actorA
是否是peg
,我们已经知道actorA是一个球!为什么它会走到这里,而不是在第四条if
语句中
我唯一能假设的是,cast的工作原理与c#不同,那就是它发现actorA
实际上是Ball
类型的Actor
派生自Actor
,然后它发现当执行static\u cast(actorA)
时,它发现Peg
也派生自Actor
,所以这是一个有效的测试?这一切都可以归结为我是如何误解了static_cast的用法的。我怎样才能实现我所需要的?:)
我真的很不安,在我看来,这就像是一次冗长的野蛮施放尝试,里面有大量荒谬的if
语句。我相信有一种更优雅的方法可以实现对Peg
和Ball
的简单转换,具体取决于actorA
和actorB
中的实际类型
希望有人能帮上忙!:)
非常感谢。要在运行时识别对象类型,您应该
动态\u cast
而不是静态\u cast
。但你真的应该重新考虑你的设计。可能(我对objective-c没有任何了解)您应该在基类中创建一个虚拟方法Hitbybyball
,并在派生类中重写实现(如果需要)。你可以调用这个方法,没有任何转换。因为这是Objto-C代码(不是C++,按标题),为什么不直接调用:
[actorA hitByBall];
[actorB hitByBall];
已更新:如果您要向其发送消息的对象为nil
,则该对象将被忽略。如果向其发送消息的对象未实现“hitByBall”,则会出现异常“selector not Recognited”,除非在基类(Actor
)中放置了空定义
然后,您可以删除您的
ball
和peg
声明以及所有static\u cast
s(即使在C++中也是不正确的)。看起来您正在寻找。如果两个对象都符合NSObject协议,则只需检查哪一个是哪一种类型-实际的消息传递不受指针静态类型的限制:
if ( [actorA isKindOfClass:[Peg class ]]
&& [actorB isKindOfClass:[Ball class]])
{
[actorA hitByBall];
}
else if ( [actorB isKindOfClass:[Peg class ]]
&& [actorA isKindOfClass:[Ball class]])
{
[actorB hitByBall];
}
错误:无法将“actorA”(类型为“struct Actor*”)动态转换为“struct Ball*”(源类型不是多态的)您可以发布struct A和struct Ball的声明吗?“除了在测试代码中,不要使用动态转换。如果您需要在unittest之外以这种方式在运行时了解类型信息,您可能存在设计缺陷。”-Google,为了支持您重新考虑设计的建议,感谢各位的评论,我重新评估了我的方法,并按照Johnsyweb的建议采用多态方法。然而,这仍然让我对静态施法感到不满。当它是
Ball
类型时,为什么对Ball
和Peg
都返回true?static\u cast
没有返回true
,而是返回指向actorA
或actorB
的指针。与使用RTTI的dynamic_cast
不同,不执行运行时检查。GetUserData()的返回类型是什么?它将是Ball
或Peg
。它可以改变。static\u cast
不是这样工作的。你把static\u cast
误认为dynamic\u cast
。两者都在根级别继承NSObject,这一点很好。我确实考虑过了,但我认为由于某种原因坚持C++测试后我再也没有回来了。谢谢乔治,谢谢约翰西。在重新思考了我的实现之后,正如许多人所建议的那样,我同意你们的观点,在进一步研究和认识到所有的objective c方法都是有效的“虚拟”之后,我不能简单地实现基本方法,是的,正如你们所说,只是为Peg实现一个Hitbybyball,其他类将忽略。谢谢。一般情况下不是这样的。如果一个对象没有实现一个方法,您将得到一个选择器无法识别的异常。你们俩可能在说什么