C ++函数指针和类
时间:2020-03-05 18:52:42 来源:igfitidea点击:
说我有:
void Render(void(*Call)()) { D3dDevice->BeginScene(); Call(); D3dDevice->EndScene(); D3dDevice->Present(0,0,0,0); }
只要我要渲染的函数是一个函数或者一个"静态"成员函数,就可以了:
Render(MainMenuRender); Render(MainMenu::Render);
但是,我真的希望也能够使用类方法,因为在大多数情况下渲染功能将要访问成员变量,而Id则不希望将类实例设置为全局实例,例如
Render(MainMenu->Render);
但是我真的不知道该怎么做,仍然允许使用函数和static
成员函数。
解决方案
回答
我们可以创建一个包装函数void Wrap(T * t)
,该包装函数仅调用t-> Call()
,并使Render
与对象一起使用此类函数。那是:
void Wrap(T *t) { t->Call(); } void Render(void (*f)(T *), T *t) { ... f(t); ... }
回答
有很多方法可以为这只猫蒙皮,包括模板。我最喜欢的是Boost.function,因为从长远来看,我发现它是最灵活的。还可以阅读Boost.bind上的绑定成员函数以及许多其他技巧。
它看起来像这样:
#include <boost/bind.hpp> #include <boost/function.hpp> void Render(boost::function0<void> Call) { // as before... } Render(boost::bind(&MainMenu::Render, myMainMenuInstance));
回答
我通过定义一个全局函数" Call"来做到这一点,该函数接受一个指向实例的指针作为成员
void CallRender(myclass *Instance) { Instance->Render(); }
因此渲染变为:
void Render(void (*Call)(myclass*), myclass* Instance) { ... Call(Instance); ... }
我们对render的调用是:
Render(CallRender, &MainMenu);
我知道这很丑陋,但是为我工作(我在使用pthreads)
回答
回答
关于C ++常见问题解答:指向成员的指针又如何呢?
回答
我们可以使用以下方法声明指向类T的成员函数的函数指针:
((object).*(ptrToMember)) So you won't be able to acheive this without changing the signature of your render method. This article explains why this is generally a bad idea. A better way might be to define a "Renderer" interface which your classes that have render methods can implement and have that be the parameter type of your main Render method. You could then write a "StaticCaller" implementation to support the calling of your static methods by reference. eg (My C++ is really rusty, I haven't compiled this either). void Render(IRenderer *Renderer) { D3dDevice->BeginScene(); Renderer->Render(); D3dDevice->EndScene(); D3dDevice->Present(0,0,0,0); } // The "interface" public class IRenderer { public: virtual void Render(); }; public class StaticCaller: public IRenderer { void (*Call)(); public: StaticCaller((*Call)()) { this->Call = Call; } void Render() { Call(); } };
并将其调用为:
typedef void (T::*FUNCTIONPOINTERTYPE)(args..) FUNCTIONPOINTERTYPE function;
用可变的参数,类型,返回值等将其外推到有用的currying系统中是单调且令人讨厌的。我已经听说了有关上述Boost库的好消息,因此建议我们在进行任何大动作之前先进行研究。
代码数量不匹配