1

1 月に予定されているコースワークのために、小さな DirectX エンジンの開発を開始しました。パフォーマンスが向上するかどうかを調べるために、仮想をまったく使用しないようにしたいと考えました (仮想がすべて悪いわけではないことはわかっていますが、仮想がなくても可能かどうかを確認したかっただけです)。

単純な StateManager をいじり始めたとき、バーチャルを避けるのは難しくなりましたが、これが私の現在のアプローチです。

#include <boost\function.hpp>
#include <boost\bind.hpp>

template <class Derived>
struct TBaseState {
  bool update(float delta) {
    return static_cast<Derived *>(this)->update(delta);
  };
};

struct CTestState : TBaseState<CTestState> {
  bool update(float delta) {
      return true;
  }
};

class StateManager
{
public:
    template <class StateClass> static void setState(StateClass nextState)
    {
        m_funcptrUpdate = boost::bind(&TBaseState<StateClass>::update,     boost::ref(nextState), _1);
    }
    static bool update(float delta) 
    {
        return m_funcptrUpdate(delta);
    }
protected:
private:
    static boost::function<bool (float)> m_funcptrUpdate;
};

Visual Studio 2010 の Intellisense はすべて問題ないように見えますが、プログラムをコンパイルして StateManager を非常に基本的な方法でテストしたい場合は、次のようにします。

CTestState* t = new CTestState(); 
StateManager::setState(*t);
StateManager::update(0.0f);

リンク フェーズ中に次のエラーがスローされます。

error LNK2001: unresolved external symbol "private: static class boost::function<bool __cdecl(float)> StateManager::m_funcptrUpdate" (?m_funcptrUpdate@StateManager@@0V?$function@$$A6A_NM@Z@boost@@A)

明らかに彼はバインドされた関数を見つけることができませんが、どうすればこの問題を解決できますか? 一部のクラスに直接 boost::bind を使用すると、同様のエラーが発生します。私はコンピューター サイエンスの学生なので、ブーストのない洞察やアプローチ (bind1st など) にも興味があります。

編集: C++11 Variadic テンプレートの使用も考えていましたが、コースワークの要件の 1 つは VS2012 に固執することです。

4

1 に答える 1

1

静的クラス メンバーにはストレージを指定する必要があります。それらはextern変数のようなものです。.cppクラス定義の外で、ファイルの 1 つに定義を追加します。

boost::function<bool (float)> StateManager::m_funcptrUpdate;

また、このコードでは:

template <class StateClass> static void setState(StateClass nextState)
{
    m_funcptrUpdate = boost::bind(&TBaseState<StateClass>::update,
        boost::ref(nextState), _1);
}

ローカル変数への参照を保存し続けていますnextState。その参照はsetState返品後に無効になります。

于 2012-11-28T01:20:30.193 に答える