嘿我正在尝试使用SFML创建一个非常简单的GUI,我希望能够在构造函数中将一个函数附加到我的Button类,因此用户可以定义当按钮是什么时会发生什么压。
我之前和GLUT工作过一段时间,注意到这些问题:
glutReshapeFunc(Resize);
glutDisplayFunc(Draw);
当调整窗口大小或显示窗口时,显然定义了应该调用的函数。我想要一个与我的按钮完全相同的东西,所以在构造时你可以定义应该调用哪个函数。 我希望能够传递一个函数名称就像过剩一样,没有定义一个新的类来覆盖虚拟的功能。
无论如何.....我如何完成这个或类似的东西?谢谢!
答案 0 :(得分:2)
您可以使用以下方式存储回叫: std::function
(对于C ++ 0x; boost::function
也可用且具有类似的接口。)
#include <functional>
class Button {
public:
template<typename T>
explicit
Button(T const& t): callback(t) {}
void
press()
{
callback();
}
private:
std::function<void()> callback;
};
// example use with a lambda
Button b([] { do_stuff(); });
b.press(); // will call do_stuff
答案 1 :(得分:1)
在C ++中,最好使用virtual
函数方法来解决此类问题。从长远来看,这更易于维护。
您可以选择重新设计一些代码,您可以在其中拥有各种子类的通用句柄。现在基于所选的子类,您可以调用特定的函数。例如:
class Shape
{
public:
virtual void Resize () = 0;
virtual void Draw () = 0;
};
class Triangle : public Shape
{
public:
// implement above to functions
};
class Square : public Shape
{
public:
// implement above to functions
};
现在,只需传递Shape*
的句柄,然后调用上面的抽象方法;
void foo(Shape *p)
{
p->Resize();
}
答案 2 :(得分:0)
(重写了一切),我误解了这个问题。
您似乎想要将普通的旧函数指针传递给其他函数。你需要做的只是传递你想要的函数的名称,但是在if
(或类似的东西)中这样做,所以传递的函数实际上是你想要的:
if(i am feeling lucky today){
glutDisplayFunc(DrawMyLuckyShape);
}else{
glutDisplayFunc(DrawAFoo);
}
坏消息是,由于C是一种讨厌的语言,你不能设置为你的函数传递额外的参数(即使用闭包)。因此,你需要依赖a)被调用的函数被调用的一些参数,或者b)看一些全局状态的函数。