虽然我看到大量关于虚函数调用它们的具有相似名称的子/父类(super class)函数的 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 类型的子节点),那么这个调用是如何运行的(当非虚拟的并且按我的意愿运行时,例如:调用正确的函数)?
2) 当它搞砸时,vTable 是否只是指向一个垃圾位置,恰好总是相同的函数?
注意:在 cocos2d(和 X)中,场景是层的子类,它是 CCObject 的子类。 CCObject 确实包含被调用的函数,但名称和参数差异很大,我不明白为什么会调用名称和参数完全不同的函数。
我愿意接受与此相关的任何引用资料和良好的文档。我怀疑我的类型转换(设置为重新解释以强制绕过所有内容)可能是为什么虚拟函数每次运行都指向相同的函数,包括当我将签名更改为 bool 而不是 void 并清理构建时.
注意:XCode 是我所在的环境。我也不认为它正在使用 LLVM。我会尝试调整它,看看会发生什么。
和其他人一样,我不认为我完全理解 vFunctions,尽管我知道抽象类的使用和强制覆盖。 (作为第一个使用该函数的类,我现在不明白为什么它需要是虚拟的,但由于我正在做的事情,我确实计划在子类中扩展该函数)。
谢谢, 史蒂夫·杰
最佳答案
reinterpret_cast
不会正确向下转换。请记住,基本子对象可能不在完整对象的开头。
对向上转换使用隐式转换,对向下转换使用static_cast
或dynamic_cast
,对交叉转换使用dynamic_cast
。它们将在需要时包括适当的偏移量,而不仅仅是像 reinterpret_cast
那样返回相同的地址。
而且这些都不会让您介于父对象和成员(非基础)子对象之间。
到目前为止,完全避免转换是最好的。
关于c++ - 虚函数调用错误函数,在C++和Cocos2dX中完全不同的名字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10354619/