我正在尝试自学一些C ++,作为一个初始项目,我想创建用于对单个变量的函数执行牛顿方法的代码。我想创建一个类ObjectiveFunction
来存储目标函数,一阶导数和二阶导数的用户定义函数。
我希望ObjectiveFunction
的构造函数取0到3个参数,其中参数本身就是函数:
// ObjectiveFunction.h
// Class definition for an Objective Function object.
#ifndef OBJECTIVE_H
#define OBJECTIVE_H
class ObjectiveFunction
{
public:
// Constructors
// Default constructor
ObjectiveFunction();
// Constructor with just objective function.
ObjectiveFunction(double f(double));
// Constructor with objective function and derivative function.
ObjectiveFunction(double f(double), double fp(double));
// Constructor with objective, derivative, and second derivative functions.
ObjectiveFunction(double f(double), double fp(double), double fpp(double));
// Methods
void setObjectiveFunction(double f(dobule));
void setDerivativeFunction(double f(double));
void setSecondDerivativeFunction(double f(double));
double evalObjectiveFunction(double);
double evalDerivativeFunction(double);
double evalSecondDerivativeFunction(double);
private:
// Storage for the functions.
// This is the part I'm not sure of.
// Attempt with function pointers
double (*objFunc)(double);
double (*d1Func)(double);
double (*d2Func)(double);
};
#endif // OBJECTIVE_H
我如何创建本身就是函数的私有数据成员。我想创建函数对象(除了私有)可以像foo.obj_func(3.0)
或foo.deriv_func(3.0)
那样访问,其中obj_func
由构造函数根据用户传递给的函数设置类。
这样做的正确方法是什么?如果有一种方法不依赖于使用指向函数对象的指针,那将是最好的,但我想如果这是唯一的方法那么我就必须学习它。
答案 0 :(得分:3)
使用std::function<double(double)>
。这将使您能够轻松存储所有功能类型。
答案 1 :(得分:0)
在决定实施技术之前,你有几个选择......
创建ObjectiveFunction
后,您需要一种方法来在设置后更改功能吗?您是否希望对您接受的“函数”更加灵活(即'functor'(基本上是实现函数调用运算符的任何东西)是否可以接受)?你是否希望使用ObjectiveFunction
的东西能够使用任何ObjectiveFunction
可互换的,而不管它在构造它时作为参数给出了什么函数?
你在这里选择了一种非常动态的方法。您真正需要做的唯一选择是使用函数指针还是::std::function
对象。 ::std::function
对象可以引用任何实现函数调用运算符的东西(例如::std::bind
的结果)。函数指针只能引用普通旧函数。
就个人而言,我会调查一个模板化的ObjectiveFunction
。部分是因为它调用的函数将在编译时设置,编译器可以更好地优化它们。使用寻根技术,您将会调用它们。因此,在某些情况下,这可能会给您带来显着的加速。
答案 2 :(得分:0)
函数指针可以工作,或者,如果您只是在允许多个实现而不更改调用代码的方法之后,则可以使用继承。
查看函数指针与继承技术的比较here。
继承解决方案会像这样;首先创建一个实现所需接口的基类:
class BaseObjectiveFunction
{
BaseObjectiveFunction();
virtual ~BaseObjectiveFunction();
virtual double EvalObjectiveFunction(double);
virtual double EvalDerivativeFunction(double);
virtual double EvalSecondDerivativeFunction(double);
}
然后实现一个具有所需功能的继承类:
class LogLikelihood: public BaseObjectiveFunction
{
public:
LogLikelihood();
~LogLikelihood();
virtual double EvalObjectiveFunction(double);
virtual double EvalDerivativeFunction(double);
virtual double EvalSecondDerivativeFunction(double);
// Example of a function to pass in some data which the calculations rely on
bool SetInputData(double* somedata, int dataLen);
}
最后,要调用此代码,您需要创建一个指向基类的指针,并指向您感兴趣的实现(以类似于传递函数指针的方式):
LogLikelihood* pOF1 = new LogLikelihood(); // Create an instantiation of a specific solver
BaseObjectiveFunction* pCaller = pOF1; // Establish a pointer to the interface class and at the specific implementation.
// Now whatever calls the evaluate function can just use the pCaller and doesn't have to worry about the actual implementation.
pCaller->EvalObjectiveFunction(1.5);
这将调用两个底层实现,这是(我认为)你真正想要的。
答案 3 :(得分:0)
#include <stdio.h>
class MyClass
{
public:
typedef int(MyClass::*FunctionPointer)(int);
FunctionPointer func;
void Setup(int selector)
{
switch (selector)
{
case 1:
{
this->func = (FunctionPointer)&MyClass::Test1;
break;
}
case 2:
{
this->func = (FunctionPointer)&MyClass::Test2;
break;
}
}
}
void Call()
{
(this->*func)(10);
}
void Test1(int a)
{
printf("test1\n");
}
void Test2(int a)
{
printf("test2\n");
}
};
int main()
{
MyClass *instance = new MyClass();
instance->Setup(1);
instance->Call();
instance->Setup(2);
instance->Call();
return 0;
}