-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 に答える