虚拟方法或函数指针 [英] Virtual Methods or Function Pointers
问题描述
在C ++中实现多态行为时,可以使用纯虚方法,也可以使用函数指针(或函子)。例如,异步回调可以通过以下方式实现:
When implementing polymorphic behavior in C++ one can either use a pure virtual method or one can use function pointers (or functors). For example an asynchronous callback can be implemented by:
class Callback
{
public:
Callback();
~Callback();
void go();
protected:
virtual void doGo() = 0;
};
//Constructor and Destructor
void Callback::go()
{
doGo();
}
所以要使用这里的回调,你需要覆盖doGo方法调用您想要的任何函数
So to use the callback here, you would need to override the doGo() method to call whatever function you want
typedef void (CallbackFunction*)(void*)
class Callback
{
public:
Callback(CallbackFunction* func, void* param);
~Callback();
void go();
private:
CallbackFunction* iFunc;
void* iParam;
};
Callback::Callback(CallbackFunction* func, void* param) :
iFunc(func),
iParam(param)
{}
//Destructor
void go()
{
(*iFunc)(iParam);
}
要使用回调方法,您需要创建一个函数指针
To use the callback method here you will need to create a function pointer to be called by the Callback object.
[这是我添加到问题;它不是由原始海报写的]
[This was added to the question by me (Andreas); it wasn't written by the original poster]
template <typename T>
class Callback
{
public:
Callback() {}
~Callback() {}
void go() {
T t; t();
}
};
class CallbackTest
{
public:
void operator()() { cout << "Test"; }
};
int main()
{
Callback<CallbackTest> test;
test.go();
}
每个实现的优点和缺点是什么?
推荐答案
方法1(虚拟功能)
- +在C ++中正确的方法
- - 每个回调都必须创建一个新类
- - 性能方面,通过VF-Table与函数指针相比的另外一个引用。与Functor解决方案相比,有两个间接引用。
方法2 (具有函数指针的类)
Approach 2 (Class with Function Pointer)
- +可以在C ++回调类中包装C样式函数
- +回调函数可以在回调对象创建之后更改
- - 需要间接调用可能比functor方法慢,可以在编译时静态计算-time。
方法3(类调用T函子)
Approach 3 (Class calling T functor)
- +可能是最快的方法。没有间接呼叫开销,可以完全内联。
- - 需要定义一个附加的Functor类。
- - 需要回调是在编译时静态声明的。
FWIW ,函数指针与Functors不同。 Functors(在C ++中)是用于提供通常为operator()的函数调用的类。
FWIW, Function Pointers are not the same as Functors. Functors (in C++) are classes that are used to provide a function call which is typically operator().
这里是一个示例函子以及一个模板函数,函数参数:
Here is an example functor as well as a template function which utilizes a functor argument:
class TFunctor
{
public:
void operator()(const char *charstring)
{
printf(charstring);
}
};
template<class T> void CallFunctor(T& functor_arg,const char *charstring)
{
functor_arg(charstring);
};
int main()
{
TFunctor foo;
CallFunctor(foo,"hello world\n");
}
从性能角度来看,虚拟函数和函数指针都会产生间接函数调用(即通过寄存器),虽然虚拟函数在加载函数指针之前需要额外加载VFTABLE指针。使用Functors(使用非虚拟调用)作为回调是将参数用于模板函数的最高性能的方法,因为它们可以是内联的,即使不是内联的,也不会生成间接调用。
From a performance perspective, Virtual functions and Function Pointers both result in an indirect function call (i.e. through a register) although virtual functions require an additional load of the VFTABLE pointer prior to loading the function pointer. Using Functors (with a non-virtual call) as a callback are the highest performing method to use a parameter to template functions because they can be inlined and even if not inlined, do not generate an indirect call.
这篇关于虚拟方法或函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!