我来自C#世界,因此活动和活动处理程序是日常的东西。最近我一直在研究WXWIDGETS我已经谷歌搜索了一个星期,我发现大多数C 程序员几乎不了解"事件"或"回调"一词,也许在C 的世界中是模棱两可的。
。这是事件模型的简单示例。
class A{
public:
A(){
child.MySuperClickEvent = this.HandleSuperClick;
}
private:
B child;
void HandleSuperClick(B child){
// do stuff
}
}
class B{
public:
/*TBA*/ MySuperClickEvent;
private:
void ClickPrivate(){
MySuperClickEvent(this);
}
}
B类具有自己的指定目的,完成后,它会触发事件。这个想法是,B级不应该对其领域有任何了解,使其更加重复使用。
我已经阅读了有关std :: function<>的功能指针。所有这些似乎都在处理静态功能时以例子为例,但是一旦谈论成员"就开始变得油腻。
总而言之,问题很简单。如何制作可以在外部分配给成员的会员函数指针?
实施此类功能的方法有很多,在内存开销方面有所不同,支持多少回调,线程安全性,例如使用,例如 weak_ptr
s查看涉及的对象是否仍然存在等。
就像一种让您入门的品味一样 - 这是一个简单的单线线程"观察者"实现,基本上是您在问题中要求的事情:
#include <iostream>
#include <list>
struct Observer
{
virtual ~Observer() { }
virtual void on_event_x() { }
};
class Observable
{
public:
void add_observer(Observer& o)
{
observers_.push_back(&o);
}
void do_some_stuff()
{
std::cout << "before 1st eventn";
fire_event_x();
std::cout << "between 1st & 2nd eventsn";
fire_event_x();
std::cout << "after 2nd eventn";
}
private:
std::list<Observer*> observers_;
void fire_event_x()
{
for (auto& observer : observers_)
observer->on_event_x();
}
};
struct My_Observer : Observer
{
My_Observer(int id) : id_(id) { }
void on_event_x() override
{
std::cout << "My_Observer::on_event_x() id " << id_ << 'n';
}
int id_;
};
int main()
{
My_Observer my_observer_1 { 1 };
My_Observer my_observer_2 { 2 };
Observable x;
x.add_observer(my_observer_1);
x.add_observer(my_observer_2);
x.do_some_stuff();
}
运行时输出:
before 1st event
My_Observer::on_event_x() id 1
My_Observer::on_event_x() id 2
between 1st & 2nd events
My_Observer::on_event_x() id 1
My_Observer::on_event_x() id 2
after 2nd event
如果您不适合您的功能,请确切地说明为什么。
因为这个问题被标记为 wxWidgets
,让我回答更狭窄的变体,即如何将成员函数用作wxwidgets中的事件处理程序:
这是在可以直接与成员函数一起使用的bind()方法的帮助(您将指针传递给函数本身,并将其调用的对象)或任何任意函数来完成的,即使用标准函数调用语法调用,例如std::function<>
对象,该对象依次可用于存储任何可呼叫对象。