对于即将开始的课程,我试图避免虚拟,看看我是否可以挤出更高的性能/内存效率。当我想要实现StateManager时,问题就出现了(课程原型是一个小游戏)。
为了实现这一点,我有一个模板来“statif”当前状态的成员函数调用。
一个示例状态是:
struct TestState {
bool update(float delta) {
return true;
}
};
现在,状态管理器应该能够接受任何State-Class并绑定更新功能。 使用boost :: bind和boost :: function很容易实现这一点,但是与虚拟相比,性能有所下降,所以我想看看是否有可能没有提升。
理论上,如果State是一个只包含静态函数的类/结构,那么这将很容易,但这也增加了不灵活性和更多的静态初始化混乱。
StateManager当前版本是:
class StateManager
{
public:
template <typename S> static void set(S* state)
{
#define UPDATE_ID 0
StateFunctionHandler<UPDATE_ID, S, bool, float>::bind(std::mem_fun1(&S::update), state);
m_funcUpdate = StateFunctionHandler<UPDATE_ID, S, bool, float>::exec;
}
static bool update(float delta)
{
return m_funcUpdate(delta);
}
typedef bool (*funcUpdate)(float);
private:
static funcUpdate m_funcUpdate;
};
StateFunctionHandler是负责将成员函数包装在StateFunctionHandler的静态成员中的模板。模板的第一个参数是一个ID,用于强制多个模板用于具有相同返回类型和参数的函数。
在代码中它看起来像这样:
template <int ID, typename S, typename R, typename A>
struct StateFunctionHandler
{
static void bind(std::mem_fun1_t<R, S, A> f, S* s)
{
func = f;
pState = s;
}
static R exec(A arg)
{
return func(pState, arg);
}
static std::mem_fun1_t<R, S, A> func;
static S* pState;
};
现在的问题是为使用的情况初始化StateFunctionHandler的模板化静态成员,因为我们需要强制编译器初始化它们。
在这些类的关联cpp文件中,静态成员被初始化:
template <int ID, typename S, typename R, typename A> std::mem_fun1_t<R, S, A> StateFunctionHandler<ID, S, R, A>::func;
template <int ID, typename S, typename R, typename A> S* StateFunctionHandler<ID, S, R, A>::pState = NULL;
StateManager::funcUpdate StateManager::m_funcUpdate = NULL;
但是我收到StateFunctionHandler :: func和:: pState的链接错误(LNK2001),因此编译器似乎没有初始化StateFunctionHandler的静态成员。
用例:
TestState* t = new TestState();
StateManager::set(t);
StateManager::update(0.1f);
再说一遍,我不想使用boost,这是一个实验,看看我是否可以在这个用例中避免虚函数并且也有性能。
答案 0 :(得分:1)
您应该将静态模板类成员的初始化移动到头文件中。
它应该在每个实例化模板的翻译单元中可见,与非静态模板类成员相同。