C++ 中的回调给班级成员
我们为客户提供了一个简单的通讯库。
我的问题是:如何保存指向客户类中方法的指针?
Library.h
是头文件,其中包含我们的客户建立通信所需的所有方法。
library.cpp
是我们的代码。在这里的某个地方,我必须保存来自客户的回调函数方法的指针。
customer.cpp
是客户如何使用我们的库的示例。
library.h:
// This is the header file what our customer gets
class Library {
public:
template <class Object, class Function>
void SetCallback(Object &obj, Function f);
};
library.cpp:
struct T_CUSTOMER {
Object o; // <- ???
Function f; // <- ???
} customer;
void Library::SetCallback(Object &obj, Function f) {
//Saving the method from our costumer
customer.o = obj; // <- ???
customer.f = f; // <- ???
}
void someFunction(void) {
// here i want to call the method from the customer
customer.o->customer.f(); //<- ???
}
customer.cpp:
class AnyCustomerClass {
private:
Library lib;
public:
AnyCustomerClass() {
//< here the customer sets his method which I should call
lib.SetCallback(this, &AnyCustomerClass::callback());
}
callback() {
// do something
}
}
感谢您的帮助!
We have a simple communication library for our customers.
My problem is: How can I save a pointer to a method from a class of our customer?
Library.h
is the header file with all the methods our customer need to establish a communication.
library.cpp
is our code. Somewhere here i have to save the pointers to the method of the callback function from our customer.
customer.cpp
is an example how a customer uses our library.
library.h:
// This is the header file what our customer gets
class Library {
public:
template <class Object, class Function>
void SetCallback(Object &obj, Function f);
};
library.cpp:
struct T_CUSTOMER {
Object o; // <- ???
Function f; // <- ???
} customer;
void Library::SetCallback(Object &obj, Function f) {
//Saving the method from our costumer
customer.o = obj; // <- ???
customer.f = f; // <- ???
}
void someFunction(void) {
// here i want to call the method from the customer
customer.o->customer.f(); //<- ???
}
customer.cpp:
class AnyCustomerClass {
private:
Library lib;
public:
AnyCustomerClass() {
//< here the customer sets his method which I should call
lib.SetCallback(this, &AnyCustomerClass::callback());
}
callback() {
// do something
}
}
Thanks for any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
基本思想是,您定义一个抽象回调类,该类实际上传递给您的接口。这个回调传递单个 int 参数的函数:
此类允许您的实现无需了解需要回调的代码。当然,要调用一个类,您确实需要一个了解其目标的 Callback 实例。因此,您还提供了一个模板化子类,使您的库的用户可以轻松地将其类之一中的方法绑定到通用回调的实例:-
要从其类创建回调的实例,代码将看起来像这样。调用也很简单:
总之:Library.h 看起来像这样。定义抽象回调类、您的库类以及客户用来包装其类及其回调方法的模板化实用程序类:
The basic idea is, you define an abstract Callback class, which actually gets passed to your interface. This one calls back to a function passing a single int parameter:
This class allows YOUR implementation to be free from knowledge of the code you need to call back into. Of course, to call into a class, you do need an instantiation of Callback that DOES have knowledge of its target. So you then also provide a templated child class that makes it easy for users of your Library to to bind a method in one of their classes to an instance of the generic Callback :-
To create an instance of the callback from their class, code would look like this. And the invocation is simple too:
In Summary: Library.h then would look like this. Define the abstract callback class, your library class, and the templated utility class that the customer uses to wrap their their class and its callback method with:
基本思想是在虚拟函数调用后面隐藏对象和函数(代码中的
Object
和Function
)的确切类型,并将两者包装在抽象接口中(这是“类型擦除”惯用语)。然后,您可以让您的客户通过模板接口从您的“基本回调”类型派生。
有关教程,请参阅此网站上的第 4 部分。或者看看 Boost.Function 和 < a href="http://www.boost.org/doc/libs/1_45_0/libs/bind/bind.html" rel="nofollow">Boost.Bind 工作(他们正是这样做的,尽管使用稍微强大的界面)
The basic idea is to hide the exact type of the object and function (
Object
andFunction
in your code) behind a virtual function call, and wrap both in an abstract interface (This is the 'type erasure' idiom).You can then let your customers derive from your "basic callback" type via a template interface.
For a tutorial, see part 4. on this website. Or take a look at how Boost.Function and Boost.Bind work (they do exactly that, although with a slightly more powerful interface)
最简单、最灵活的方法是使用 std::function。
假设我有一个函数(但这也可以是一个类),它需要调用传递给它的另一个函数。我这样定义这个函数:
有关如何使用它的第一个示例是使用全局函数(或静态方法),如下所示:
我只是将函数指针传递给 myFunction。
我还可以使用 lambda 表达式,如下所示:
第三个示例(这可能是您想要的)是传递已定义函数运算符的类实例,如下所示:
正如您所见,使用 std::函数中,我可以传递 3 种不同类型的“函数引用”(函数指针、lambda 和函子)。
The easiest and most flexible way is to use std::function.
Suppose I have a function (but this could be a class as well), which needs to call another function passed to it. I define this function like this:
A first example on how to use this is using a global function (or static method), like this:
I just pass the function pointer to myFunction.
I can also use a lambda expression, like this:
The third example (and which is probably what you want), is to pass a class instance that has defined the function-operator, like this:
As you can see, using std::function, I can pass 3 different types of 'references to functions' (function pointers, lambda's and functors).
下面的代码似乎以某种方式工作,但恕我直言,整个设计非常可疑。
http://codepad.org/9QDcMJAg
The code below seems to work somehow, but imho the whole design is very suspicious.
http://codepad.org/9QDcMJAg
感谢您的回答,但我在实现方面仍然存在问题(我通常用java或C(微控制器)进行编程。从未想过在C++中实现这一点对我来说会如此复杂))
我喜欢使用Chris的建议贝克.
library.h
customer.cpp
Library.cpp
Thanks for the answers, but i still have problems with the implementation (I normaly program in java or in C (microcontoller). Never thought it would be so complicated for me to realise this in c++))
I like to use the suggestion from Chris Becke.
library.h
customer.cpp
Library.cpp