虽然我看到过多的虚拟函数的Stack Overflow问题和答案调用了类似名称的子/超类函数,但我得到了这个:
CCLog("Yay"); //ensure it's called
CCScene * tScene = TitleDescription::scene(); //grab the scene
TitleDescription * t = reinterpret_cast<TitleDescription *>(tScene); //Unsure why this even works when I think about it, a scene is returned but the below call:
t->loadWithDataFrom("Information.xml", "story"); //calls setScaleX on CCObject instead.
CCDirector::sharedDirector()->replaceScene(tScene ); //runs with an empty scene on one condition
使用loadWithData加载场景的条件是我使函数为void name(types)。我遵循了cocos2d-x的模式并使用了虚拟,在这种情况下,它调用了setScaleX,我使用了调试器并进入了它。
我有两个问题。
1)如果scene()函数返回一个场景(具有TitleDescription类型的子节点),那么这个调用是如何运作的(当非虚拟并按我的意愿运行时,例如:调用正确的函数)? / p>
2)当它搞砸时,vTable是否只是指向一个垃圾位置,这恰好是同一个函数?
注意:在cocos2d(和X)中,场景是图层的子类,它们是CCObject的子类。 CCObject确实包含了被调用的函数,但是名称和参数差别很大,而且我不明白为什么一个名称和参数完全不同的函数会被调用。
我对这方面的任何参考和良好文档持开放态度。我怀疑我的演员(设置为重新解释只是强制绕过一切),可能是为什么虚函数指向每次运行的相同函数,包括当我将签名更改为bool而不是void时,并清理构建
注意:XCode是我所处的环境。我不相信它也在使用LLVM。我会尝试调整,看看会发生什么。
和其他人一样,我不认为我完全理解vFunction,即使我知道使用抽象类和强制覆盖。 (作为第一个使用该函数的类,我不明白为什么它此时需要是虚拟的,但我确实计划在子类中扩展函数,因为我正在做的事情。)
谢谢, Steve J
答案 0 :(得分:3)
reinterpret_cast
不会正确转发。请记住,基础子对象可能不在完整对象的开头。
对于向上转换使用隐式转换,对于向下转换使用static_cast
或dynamic_cast
,对于横向广播使用dynamic_cast
。它们将在需要时包含适当的偏移量,而不仅仅按reinterpret_cast
的方式返回相同的地址。
这些都不会让你在父和成员(非基础)子对象之间。
完全避免演员表是最好的。