-2

我有一个带有一些虚函数的基类:

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->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;
}
4

2 回答 2

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 论坛?

于 2013-06-05T15:23:31.820 回答
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;
于 2013-06-05T15:36:43.737 回答