C++ 如何将类成员函数作为回调传递?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/400257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I pass a class member function as a callback?
提问by ofer
I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.
我使用的 API 要求我将函数指针作为回调传递。我正在尝试从我的班级中使用此 API,但出现编译错误。
Here is what I did from my constructor:
这是我从构造函数中所做的:
m_cRedundencyManager->Init(this->RedundencyManagerCallBack);
This doesn't compile - I get the following error:
这不会编译 - 我收到以下错误:
Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member
错误 8 错误 C3867:“CLoggersInfra::RedundencyManagerCallBack”:函数调用缺少参数列表;使用 '&CLoggersInfra::RedundencyManagerCallBack' 创建指向成员的指针
I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack
- didn't work for me.
我尝试了使用的建议&CLoggersInfra::RedundencyManagerCallBack
- 对我不起作用。
Any suggestions/explanation for this??
对此有何建议/解释?
I'm using VS2008.
我正在使用 VS2008。
Thanks!!
谢谢!!
采纳答案by Johannes Schaub - litb
That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.
这是行不通的,因为成员函数指针不能像普通函数指针一样处理,因为它需要一个“this”对象参数。
Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:
相反,您可以按如下方式传递静态成员函数,在这方面,它们类似于普通的非成员函数:
m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);
The function can be defined as follows
该函数可以定义如下
static void Callback(int other_arg, void * this_pointer) {
CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
self->RedundencyManagerCallBack(other_arg);
}
回答by Joseph Garvin
This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.
这是一个简单的问题,但答案却出奇的复杂。简短的回答是你可以用 std::bind1st 或 boost::bind 做你想做的事情。更长的答案如下。
The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.
编译器建议您使用 &CLoggersInfra::RedundencyManagerCallBack 是正确的。首先,如果 RedundencyManagerCallBack 是一个成员函数,则该函数本身不属于 CLoggersInfra 类的任何特定实例。它属于类本身。如果您之前曾经调用过静态类函数,您可能已经注意到您使用了相同的 SomeClass::SomeMemberFunction 语法。由于函数本身是“静态的”,因为它属于类而不是特定实例,因此您使用相同的语法。'&' 是必要的,因为从技术上讲,您不直接传递函数——函数在 C++ 中不是真正的对象。相反,您在技术上传递的是函数的内存地址,即指向函数指令在内存中开始位置的指针。
But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.
但在这种情况下,这只是问题的一半。正如我所说, RedundencyManagerCallBack 函数不“属于”任何特定实例。但听起来您想将它作为回调传递给特定实例。要了解如何做到这一点,您需要了解真正的成员函数是什么:带有额外隐藏参数的常规未定义在任何类中的函数。
For example:
例如:
class A {
public:
A() : data(0) {}
void foo(int addToData) { this->data += addToData; }
int data;
};
...
A an_a_object;
an_a_object.foo(5);
A::foo(&an_a_object, 5); // This is the same as the line above!
std::cout << an_a_object.data; // Prints 10!
How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:
A::foo 有多少个参数?通常我们会说 1。但实际上,foo 确实需要 2。看看 A::foo 的定义,它需要 A 的特定实例,以便“this”指针有意义(编译器需要知道什么 '这是)。通常指定“this”的方式是通过语法 MyObject.MyMemberFunction()。但这只是将 MyObject 的地址作为第一个参数传递给 MyMemberFunction 的语法糖。类似地,当我们在类定义中声明成员函数时,我们不会将“this”放在参数列表中,但这只是语言设计者为节省键入而提供的礼物。相反,您必须指定一个成员函数是静态的,以自动选择退出它以获取额外的“this”参数。
struct A {
int data;
};
void a_init(A* to_init)
{
to_init->data = 0;
}
void a_foo(A* this, int addToData)
{
this->data += addToData;
}
...
A an_a_object;
a_init(0); // Before constructor call was implicit
a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);
Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. Thus why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).
回到你的例子,现在有一个明显的问题。'Init' 需要一个指向带一个参数的函数的指针。但是 &CLoggersInfra::RedundencyManagerCallBack 是一个指向函数的指针,它有两个参数,一个是普通参数,另一个是秘密的“this”参数。因此,为什么您仍然会收到编译器错误(作为旁注:如果您曾经使用过 Python,这种混淆就是为什么所有成员函数都需要一个 'self' 参数的原因)。
The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.
处理此问题的详细方法是创建一个特殊对象,该对象保存指向所需实例的指针,并具有一个名为“run”或“execute”(或重载“()”运算符)之类的成员函数,它接受参数对于成员函数,只需在存储的实例上使用这些参数调用成员函数。但这需要您更改 'Init' 以获取您的特殊对象而不是原始函数指针,而且听起来 Init 是其他人的代码。每次出现这个问题时都创建一个特殊的类会导致代码膨胀。
So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:
所以现在,终于有了一个好的解决方案,boost::bind 和 boost::function,你可以在这里找到每个的文档:
boost::bind docs, boost::function docs
boost::bind 文档, boost::function 文档
boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the firstparameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called std::bind1st that you could use as well, but boost::bind is more general.
boost::bind 将让您获取一个函数和该函数的参数,并在该参数被“锁定”到位的地方创建一个新函数。因此,如果我有一个将两个整数相加的函数,我可以使用 boost::bind 来创建一个新函数,其中一个参数被锁定为 5。这个新函数将只接受一个整数参数,并且总是专门添加 5到它。使用这种技术,您可以将隐藏的“this”参数“锁定”为特定的类实例,并生成一个只接受一个参数的新函数,就像您想要的一样(注意隐藏参数始终是第一个参数,普通参数在其后依次排列)。查看 boost::bind 文档以获取示例,他们甚至专门讨论将其用于成员函数。从技术上讲,您也可以使用一个名为 std::bind1st 的标准函数,但 boost::bind 更通用。
Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.
当然,还有一个问题。boost::bind 将为您提供一个很好的 boost::function,但这在技术上仍然不是 Init 可能想要的原始函数指针。值得庆幸的是,boost 提供了一种将 boost::function 转换为原始指针的方法,如 StackOverflow此处所述。它如何实现这一点超出了这个答案的范围,尽管它也很有趣。
Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.
如果这看起来非常难,请不要担心——你的问题与 C++ 的几个阴暗角落相交,一旦你学会了 boost::bind 就会非常有用。
C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.
C++11 更新:您现在可以使用捕获“this”的 lambda 函数代替 boost::bind。这基本上是让编译器为您生成相同的内容。
回答by Roi Danton
This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.
此答案是对上述评论的回复,不适用于 VisualStudio 2008,但应优先用于更新的编译器。
Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind
and std::function
are available. Oneadvantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function
:
同时,您不必再使用 void 指针,并且也不需要 boost,因为std::bind
和std::function
可用。一个优点(与 void 指针相比)是类型安全,因为返回类型和参数是使用std::function
以下明确声明的:
// std::function<return_type(list of argument_type(s))>
void Init(std::function<void(void)> f);
Then you can create the function pointer with std::bind
and pass it to Init:
然后您可以创建函数指针std::bind
并将其传递给 Init:
auto cLoggersInfraInstance = CLoggersInfra();
auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
Init(callback);
Complete examplefor using std::bind
with member, static members and non member functions:
std::bind
与成员、静态成员和非成员函数一起使用的完整示例:
#include <functional>
#include <iostream>
#include <string>
class RedundencyManager // incl. Typo ;-)
{
public:
// std::function<return_type(list of argument_type(s))>
std::string Init(std::function<std::string(void)> f)
{
return f();
}
};
class CLoggersInfra
{
private:
std::string member = "Hello from non static member callback!";
public:
static std::string RedundencyManagerCallBack()
{
return "Hello from static member callback!";
}
std::string NonStaticRedundencyManagerCallBack()
{
return member;
}
};
std::string NonMemberCallBack()
{
return "Hello from non member function!";
}
int main()
{
auto instance = RedundencyManager();
auto callback1 = std::bind(&NonMemberCallBack);
std::cout << instance.Init(callback1) << "\n";
// Similar to non member function.
auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
std::cout << instance.Init(callback2) << "\n";
// Class instance is passed to std::bind as second argument.
// (heed that I call the constructor of CLoggersInfra)
auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
CLoggersInfra());
std::cout << instance.Init(callback3) << "\n";
}
Possible output:
可能的输出:
Hello from non member function!
Hello from static member callback!
Hello from non static member callback!
Furthermore using std::placeholders
you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString");
in Init
if f has a string parameter).
此外,使用std::placeholders
您可以动态地将参数传递给回调(例如return f("MyString");
,Init
如果 f 具有字符串参数,则可以使用in )。
回答by Stefan Steiger
Necromancing.
I think the answers to date are a little unclear.
死灵法术。
我认为迄今为止的答案有点不清楚。
Let's make an example:
让我们举个例子:
Supposed you have an array of pixels (array of ARGB int8_t values)
假设您有一个像素数组(ARGB int8_t 值数组)
// A RGB image
int8_t* pixels = new int8_t[1024*768*4];
Now you want to generate a PNG. To do so, you call the function toJpeg
现在您要生成一个 PNG。为此,您调用函数 toJpeg
bool ok = toJpeg(writeByte, pixels, width, height);
where writeByte is a callback-function
其中 writeByte 是回调函数
void writeByte(unsigned char oneByte)
{
fputc(oneByte, output);
}
The problem here: FILE* output has to be a global variable.
Very bad if you're in a multithreaded environment (e.g. a http-server).
这里的问题是: FILE* 输出必须是一个全局变量。
如果您处于多线程环境(例如 http 服务器)中,那就太糟糕了。
So you need some way to make output a non-global variable, while retaining the callback signature.
因此,您需要某种方法使输出成为非全局变量,同时保留回调签名。
The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.
想到的直接解决方案是闭包,我们可以使用带有成员函数的类来模拟它。
class BadIdea {
private:
FILE* m_stream;
public:
BadIdea(FILE* stream) {
this->m_stream = stream;
}
void writeByte(unsigned char oneByte){
fputc(oneByte, this->m_stream);
}
};
And then do
然后做
FILE *fp = fopen(filename, "wb");
BadIdea* foobar = new BadIdea(fp);
bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
delete foobar;
fflush(fp);
fclose(fp);
However, contrary to expectations, this does not work.
然而,与预期相反,这是行不通的。
The reason is, C++ member functions are kinda implemented like C# extension functions.
原因是,C++ 成员函数的实现有点像 C# 扩展函数。
So you have
所以你有了
class/struct BadIdea
{
FILE* m_stream;
}
and
和
static class BadIdeaExtensions
{
public static writeByte(this BadIdea instance, unsigned char oneByte)
{
fputc(oneByte, instance->m_stream);
}
}
So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.
所以当你想调用writeByte时,你不仅需要传递writeByte的地址,还需要传递BadIdea-instance的地址。
So when you have a typedef for the writeByte procedure, and it looks like this
所以当你有一个 writeByte 过程的 typedef 时,它看起来像这样
typedef void (*WRITE_ONE_BYTE)(unsigned char);
And you have a writeJpeg signature that looks like this
你有一个像这样的 writeJpeg 签名
bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t
width, uint32_t height))
{ ... }
it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.
将双地址成员函数传递给单地址函数指针(不修改 writeJpeg)从根本上是不可能的,而且没有办法绕过它。
The next best thing that you can do in C++, is using a lambda-function:
您可以在 C++ 中做的下一个最好的事情是使用 lambda 函数:
FILE *fp = fopen(filename, "wb");
auto lambda = [fp](unsigned char oneByte) { fputc(oneByte, fp); };
bool ok = TooJpeg::writeJpeg(lambda, image, width, height);
However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.
但是,由于 lambda 没有做任何不同,除了将实例传递给隐藏类(例如“BadIdea”类)之外,您需要修改 writeJpeg 的签名。
The advantage of lambda over a manual class, is that you just need to change one typedef
与手动类相比,lambda 的优势在于您只需要更改一个 typedef
typedef void (*WRITE_ONE_BYTE)(unsigned char);
to
到
using WRITE_ONE_BYTE = std::function<void(unsigned char)>;
And then you can leave everything else untouched.
然后你可以保持其他一切不变。
You could also use std::bind
你也可以使用 std::bind
auto f = std::bind(&BadIdea::writeByte, &foobar);
But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.
但这在幕后只是创建了一个 lambda 函数,然后它也需要更改 typedef。
So no, there is no way to pass a member function to a method that requires a static function-pointer.
所以不,没有办法将成员函数传递给需要静态函数指针的方法。
But lambdas are the easy way around, provided that you have control over the source.
Otherwise, you're out of luck.
There's nothing you can do with C++.
但是 lambda 是最简单的方法,前提是您可以控制源。
否则,你就不走运了。
你用 C++ 什么也做不了。
Note:
std::function requires #include <functional>
注意:
std::function 需要#include <functional>
However, since C++ allows you to use C as well, you can do this with libffcallin plain C, if you don't mind linking a dependency.
但是,由于 C++ 也允许您使用C,如果您不介意链接依赖项,则可以使用普通 C 中的libffcall来执行此操作。
Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.
从 GNU 下载 libffcall(至少在 ubuntu 上,不要使用发行版提供的包 - 它已损坏),解压缩。
./configure
make
make install
gcc main.c -l:libffcall.a -o ma
main.c:
主文件:
#include <callback.h>
// this is the closure function to be allocated
void function (void* data, va_alist alist)
{
int abc = va_arg_int(alist);
printf("data: %08p\n", data); // hex 0x14 = 20
printf("abc: %d\n", abc);
// va_start_type(alist[, return_type]);
// arg = va_arg_type(alist[, arg_type]);
// va_return_type(alist[[, return_type], return_value]);
// va_start_int(alist);
// int r = 666;
// va_return_int(alist, r);
}
int main(int argc, char* argv[])
{
int in1 = 10;
void * data = (void*) 20;
void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
// void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
// void(*incrementer1)(int abc) starts to throw errors...
incrementer1(123);
// free_callback(callback);
return EXIT_SUCCESS;
}
And if you use CMake, add the linker library after add_executable
如果使用 CMake,则在 add_executable 之后添加链接器库
add_library(libffcall STATIC IMPORTED)
set_target_properties(libffcall PROPERTIES
IMPORTED_LOCATION /usr/local/lib/libffcall.a)
target_link_libraries(BitmapLion libffcall)
or you could just dynamically link libffcall
或者你可以动态链接 libffcall
target_link_libraries(BitmapLion ffcall)
Note:
You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.
注意:
您可能希望包含 libffcall 头文件和库,或者使用 libffcall 的内容创建一个 cmake 项目。
回答by Konrad Rudolph
What argument does Init
take? What is the new error message?
需要什么论证Init
?新的错误信息是什么?
Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this
). Maybe Init
expects it as a separate argument?
C++ 中的方法指针有点难以使用。除了方法指针本身,您还需要提供一个实例指针(在您的情况下this
)。也许Init
期望它作为一个单独的论点?
回答by e.James
Is m_cRedundencyManager
able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this pageat C++ FAQ Lite for more information.
是否m_cRedundencyManager
可以使用成员函数?大多数回调设置为使用常规函数或静态成员函数。有关更多信息,请查看C++ FAQ Lite中的此页面。
Update:The function declaration you provided shows that m_cRedundencyManager
is expecting a function of the form: void yourCallbackFunction(int, void *)
. Member functions are therefore unacceptable as callbacks in this case. A static member function maywork, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *
.
更新:您提供的函数声明表明需要m_cRedundencyManager
以下形式的函数:void yourCallbackFunction(int, void *)
。因此,在这种情况下,成员函数作为回调是不可接受的。静态成员函数可能会起作用,但如果在您的情况下这是不可接受的,则以下代码也将起作用。请注意,它使用了来自void *
.
// in your CLoggersInfra constructor:
m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);
// in your CLoggersInfra header:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);
// in your CLoggersInfra source file:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)
{
((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);
}
回答by jalf
A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the thispointer), and uses a different calling convention.
指向类成员函数的指针与指向函数的指针不同。类成员采用隐式额外参数(this指针),并使用不同的调用约定。
If your API expects a nonmember callback function, that's what you have to pass to it.
如果您的 API 需要非成员回调函数,那么您必须传递给它。
回答by ofer
I can see that the init has the following override:
我可以看到 init 具有以下覆盖:
Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)
where CALLBACK_FUNC_EX
is
这里CALLBACK_FUNC_EX
是
typedef void (*CALLBACK_FUNC_EX)(int, void *);
回答by Onorio Catenacci
This question and answerfrom the C++ FAQ Litecovers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:
这个问题和答案从C ++ FAQ精简版涵盖了你的问题,参与回答的考虑相当不错,我认为。我链接的网页的简短片段:
Don't.
Because a member function is meaningless without an object to invoke it on, you can't do this directly (if The X Window System was rewritten in C++, it would probably pass references to objects around, not just pointers to functions; naturally the objects would embody the required function and probably a whole lot more).
别。
因为成员函数没有对象来调用它是没有意义的,你不能直接这样做(如果 X 窗口系统是用 C++ 重写的,它可能会传递对周围对象的引用,而不仅仅是指向函数的指针;自然是对象将体现所需的功能,可能还有更多)。
回答by M.Hefny
A simple solution "workaround" still is to create a class of virtual functions "interface" and inherit it in the caller class. Then pass it as a parameter "could be in the constructor" of the other class that you want to call your caller class back.
一个简单的解决方案“解决方法”仍然是创建一个虚函数“接口”类并在调用者类中继承它。然后将它作为参数“可能在构造函数中”传递给你想要调用你的调用者类的另一个类。
DEFINE Interface:
定义接口:
class CallBack
{
virtual callMeBack () {};
};
This is the class that you want to call you back:
这是您想给您回电的课程:
class AnotherClass ()
{
public void RegisterMe(CallBack *callback)
{
m_callback = callback;
}
public void DoSomething ()
{
// DO STUFF
// .....
// then call
if (m_callback) m_callback->callMeBack();
}
private CallBack *m_callback = NULL;
};
And this is the class that will be called back.
这是将被回调的类。
class Caller : public CallBack
{
void DoSomthing ()
{
}
void callMeBack()
{
std::cout << "I got your message" << std::endl;
}
};