C++ 虚拟函数调用了错误的函数,在C++;和Cocos2dX

C++ 虚拟函数调用了错误的函数,在C++;和Cocos2dX,c++,virtual-functions,vtable,cocos2d-x,C++,Virtual Functions,Vtable,Cocos2d X,当我看到大量关于虚拟函数调用其类似名称的子/超类函数的堆栈溢出问题和答案时,我得到了以下结论: CCLog("Yay"); //ensure it's called CCScene * tScene = TitleDescription::scene(); //grab the scene TitleDescription * t = reinterpret_cast<TitleDescription *>(tScene); //Unsure why this even works

当我看到大量关于虚拟函数调用其类似名称的子/超类函数的堆栈溢出问题和答案时,我得到了以下结论:

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
CCLog(“Yay”)//确保它被调用
CCScene*tScene=TitleDescription::scene()//抢占现场
标题说明*t=重新解释铸件(tScene)//当我思考时,不确定为什么会这样,会返回一个场景,但下面的调用:
t->loadWithDataFrom(“Information.xml”、“story”)//改为在CCObject上调用setScaleX。
CCDirector::sharedDirector()->ReplaceSecene(tScene)//在一个条件下使用空场景运行
使用loadWithData加载场景的条件是我将函数设为void name(types)。我遵循cocos2d-x的模式并使用virtual,在这种情况下,它调用setScaleX,我使用了调试器并进入其中

我有两个问题

1) 如果scene()函数返回一个场景(带有TitleDescription类型的子节点),那么这个调用是如何工作的(当非虚拟且按我的意愿运行时,例如:调用正确的函数)

2) 当它出错时,vTable是否只是指向一个垃圾位置,而垃圾位置恰好总是相同的函数

注意:在cocos2d(和X)中,场景是层的子类,它是CCObject的子类。CCObject确实包含被调用的函数,但是名称和参数差别很大,我不明白为什么一个名称和参数完全不同的函数会被调用

我愿意接受任何关于这方面的参考资料和良好的文档。我怀疑我的cast(设置为reinterpret只是为了强制绕过一切)可能是虚拟函数每次运行都指向同一个函数的原因,包括当我将签名更改为bool而不是void,并清理构建时

注意:XCode是我所在的环境。我也不相信它正在使用LLVM。我会尝试调整一下,看看会发生什么

和其他人一样,我不认为我完全理解vFunction,尽管我知道使用抽象类和强制重写。(作为这个func的第一个类,我不明白为什么现在它需要是虚拟的,但是我确实计划在子类中扩展这个函数,因为我正在做的事情)

谢谢,
Steve J

重新解释演员阵容
将无法正确地向下播放。请记住,基础子对象可能不在完整对象的开头

使用隐式转换进行上传,使用
static\u cast
dynamic\u cast
进行下载,使用
dynamic\u cast
进行交叉播放。它们将在需要时包括适当的偏移量,而不是像重新解释cast那样返回相同的地址

所有这些都不会使您介于父对象和成员(非基)子对象之间


完全避免强制转换是目前为止最好的方法。

感谢您的指导(如,向上/向下),尽管我专门使用reinterpret来避免错误检查,只是为了测试的目的。我对两件事更好奇。1) 为什么类方法返回一个CCNode,并且它以后的行为类似于一个实例,而不是静态方法返回的;2)为什么vTable工作不正确,但是没有vTable一切都正常。换句话说,演员们在没有“虚拟”的情况下工作。我可能需要做一些关于虚拟函数的研究more@StephenJ:对于非虚拟函数,情况也不正常。你在他们的
这个
参数中塞进了一个伪指针,所以你可以期望他们行为不端。我认为,一旦您了解虚拟调用的工作原理(对象包含指向函数指针数组的指针)和非虚拟调用的工作原理(编译器确定调用了哪个函数),行为就会很明显。@StephenJ:基本上,当您调用虚拟函数时,编译器生成代码从对象中查找正确的函数(除非它能证明对象的运行时类型,可能它是在前一行中创建的)。啊,再次感谢您的解释。当我看到这个并记住有一个宏,在返回之前转换节点时,它开始变得清晰起来。这就解释了为什么它会起作用。我想我可以把它和你的评论结合起来,也许可以找出它为什么调用随机函数,谢谢!s