我有一个带有一些虚函数的基类:
class cs
{
<snip>
virtual void Deactivate() = 0;
virtual void Update() = 0;
virtual void Render() = 0;
<snip>
};
然后我从这个基类派生一个类,它有Update()和Render函数。我称之为:
if (s_pActiveScene)
{
s_pActiveScene->Update();
}
注意:s_pActiveScene是指向派生类的指针。
当我在iOS,Android,Mac上运行C代码时,一切正常。它也适用于Windows的调试模式(无优化)。但是,该调用(s_pActiveScene-&gt; Update();)在Windows发行版上崩溃(仅限整个程序优化=使用链接时间代码生成)。
这是编译器的缺陷,还是我做错了什么?
编辑:从新项目获得相同的行为,使用最少的代码如下:
---- main.cpp
#include "cs.h"
#include "csMain.h"
int main(int argc, char* argv[])
{
Main.ActivateThisScene();
cs::DoUpdate();
return 0;
}
---- cs.h
#pragma once
class cs
{
public:
void ActivateThisScene();
static void DoUpdate();
virtual void Update() = 0;
protected:
static cs* s_pActiveScene;
};
---- cs.cpp
#include "cs.h"
cs* cs::s_pActiveScene = 0;
void cs::ActivateThisScene()
{
s_pActiveScene = this;
}
void cs::DoUpdate()
{
if (s_pActiveScene)
{
s_pActiveScene->Update();
}
}
---- csMain.h
#pragma once
#include "cs.h"
extern class csMain Main;
class csMain : public cs
{
public:
void Activate();
void Update();
};
---- csMain.cpp
#include "csMain.h"
class csMain Main;
void
csMain::Activate()
{
ActivateThisScene();
}
void
csMain::Update()
{
return;
}
答案 0 :(得分:2)
是的,有问题。它与静态变量初始化顺序有关,或者确实是代码生成器错误。
这是机器代码
Main.ActivateThisScene();
01361000 mov eax,dword ptr [Main (1363064h)]
01361005 mov edx,dword ptr [eax] ; this is supposed to be the 1st entry of VMT, but it is 0
01361007 mov ecx,offset Main (1363064h)
0136100C mov dword ptr [cs::s_pActiveScene (13633BCh)],ecx
cs::DoUpdate();
01361012 call edx ; access violation
您是否尝试将您的代码发布到social.msdn.microsoft.com上的VC论坛?
答案 1 :(得分:1)
它混合了多态性和静态,你可以像这样解决它:
//in csMain.cpp delete this static object
csMain Main;
//in main.cpp create it dynamically
csMain *p = new csMain;
p->ActivateThisScene();
cs::DoUpdate();
delete p;