我们说我有一些有空方法的课程:
class Foo {
private:
Sprite spr;
public:
//...
void onLeftClick();
};
让我们说当我在精灵上单击LMB时会调用此方法。现在,我有两个Foo对象:
Foo first;
Foo second;
问题是我想做某事"当我点击其中一个精灵时我的Foo对象有,但我想编写不同的"响应"对于每个特定的对象。例如,一个对象在单击时将显示文本,第二个将播放声音,第三个将使精灵移动到某个位置,然后播放声音,然后精灵将返回其开始位置。那要做的事情很多......
我知道我可能需要的是一些像Lua这样的脚本语言,但是现在我真的不熟悉脚本。有没有办法实现我只想用C ++做的事情?
答案 0 :(得分:4)
有几种方法可以做你想要的,但对于初学者你可以尝试这样的事情:
class sprite
{
// Let's say the parameters are the coordinates of the click
using click_handler_t = std::function<void(sprite&, int, int)>;
click_handler_t click_handler;
std::string name;
public:
sprite(const std::string& name) : name{name} {}
const std::string& get_name() const { return name; }
void set_click_handler(click_handler_t new_handler) {
click_handler = new_handler;
}
void on_click(int x, int y) {
click_handler(*this, x, y);
}
};
然后,当您创建精灵时,您可以添加任何类型的处理程序,只要它可以使用兼容签名进行调用。例如,使用lambda:
sprite s1{"Sprite1"};
s1.add_click_handler( [](sprite& s, int x, int y) {
std::cout << "Sprite " << s.get_name() << "clicked at ("
<< x << "," << y << ")\n";
});
或使用免费功能:
void sprite2_clicked(sprite& s, int x, int y)
{
// Some other action here
}
sprite s2{"Sprite 2"};
s2.add_click_hander(sprite2_clicked);
这实际上只是大多数GUI库使用的信号概念的一个非常基本的版本。如果您要执行此类操作,我建议您使用boost::signals2
或libsigc++
之类的正确信号库,而不是使用自己的信号库。
答案 1 :(得分:0)
C ++是一种静态类型语言。这意味着所有类型都在编译时中定义。 对象的实例发生在执行时间。
因此,本质上,C ++并不是为您设计特定对象的方法!如果你想做这样的事情,Tristan Brindle的答案是非常好的方法。在&#34;较低级别&#34;动态类型语言的类似情况正在发生。例如,您可以使用功能映射,以便调用myInstance.callFuncion["myMethodX"]()
。你找到了一种“动态化”的方法。对象的方法数量......: - )