我正在编写一个执行基本操作集的程序,但允许用户填写被调用的特定功能(并且他们在编译之前会选择这些功能)。例如,我的程序可以调用函数filter(input,&output)
,但是用户可以编写自己的过滤器。
我所读到的可能解决此问题的方法是函数指针和虚函数。看来我可以按照
int (*pt2Filter)(float,&float) = NULL;
int IIRFilter(float input, float &output);
pt2Filter=&IIRFilter;
用于函数指针。但这不能让我跟踪过滤器中的内部状态。
或者,我可以使用虚拟的
myClass
函数创建一个类filter
,然后用户将创建一个从IIR
继承并覆盖myClass
函数的filter
类。class myClass
{
virtual void Filter(float input, float &output);
...
};
class IIR : public myClass
{
float stateVariable;
virtual void Filter(float input, float &output);
}
void IIR::Filter(float input, float &output)
{ //IIR filter done here }
我想我的问题是,如何在不知道
IIR
类存在的情况下从程序中调用filter函数?或者,如果我要解决完全错误的问题,那么当我的目标是1时,该如何调用
Filter
函数:让用户定义他们想要的任何过滤器。 2:不允许用户更改我的源代码更新资料
这可能没有我最初想到的那么困难。我创建了一个头文件,用户将在其中说出他们希望使用以下行调用Filter类的函数
//User types this into "FunctionImplementations.h"
#include "IIR.h"
typedef IIR FilterImplementation;
//then I just type
#include "FunctionImplementations.h"
FilterImplementation.filter(); //Implements IIR classes filter function
最佳答案
有几种方法可以实现这种多态性。
主要问题是您需要编译时多态行为还是运行时多态行为。在第一种情况下,解决方案通常是定义一个函数(或类)模板来执行您的通用工作,并用您的通用代码调用的可调用对象的类型对其进行参数化,以完成工作的自定义部分:
// This is how you would define your generic procedure
template<typename F> void do_something(F f, ...)
{
...
f(...);
...
}
// This is how you would use it...
void my_func(...) { ... };
do_something(&my_func, ...); // with a function pointer
do_something([] (...) { ... }, ...); // with a lambda
struct my_functor { operator void () (...) { ... } };
do_something(my_functor(), ...); // with a functor
如果定义自定义行为的对象类型仅在运行时确定,则有两种可能:要么使用
std::function<>
封装回调,要么使用虚拟函数方法。我个人更喜欢前者,因为它不会强迫您仅为了实现动态多态性而创建继承层次结构。这是使用
std::function<>
对象的方式:void my_func1(int, int) { ... }
void my_func2(int, int) { ... }
std::function<void(int, int)> fxn = &my_func1;
fxn(2, 3);
...
fxn = &my_func2;
fxn(3, 4);
...
fxn = [] (int x, int y) { ... };
fxn(4, 5)
这是您可以利用它来定义通用过程的方式:
void do_something(std::function<void(int, int)> f, ...)
{
...
f(3, 4);
...
}
此时,您可以使用可以分配给
do_something()
的任何内容(即具有兼容签名的任何可调用对象)调用std::function
。关于c++ - 如何使用函数指针或虚拟函数来允许其他程序员定义函数的实现?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14464297/