我正在尝试编写一组通用数学实用程序类(根查找器、积分器等),这些类在构造时接受一个指向基类的指针,该基类定义了我希望特定算法运行的函数。基类应该只定义一个公共(public)虚拟接口(interface)(抽象的或具有默认的琐碎功能)type operator()(type inputArg)
,用户可以根据需要实现。这将允许用户只实现所需的仿函数并执行所需的计算。我的 mwe 在下面:
第一个头文件定义了抽象接口(interface)类
// BaseFunctor.h
#ifndef _BASE_FUNCTOR_H_
#define _BASE_FUNCTOR_H_
class BaseFunctor
{
public:
virtual double operator() (double x) = 0;
};
#endif
这是求解器方法之一的类
// NewtonsMethod.h
#ifndef _NEWTONS_METHOD_H_
#define _NEWTONS_METHOD_H_
class BaseFunctor;
class NewtonsMethod
{
public:
NewtonsMethod(BaseFunctor *rhsIn,
BaseFunctor *rhsPrimeIn,
double x0In);
~NewtonsMethod();
bool DetermineRoot(double &root);
private:
double x0;
BaseFunctor *rhs;
BaseFunctor *rhsPrime;
static const double EPSILON;
static const unsigned int MAX_ITER;
};
#endif
这是求解器的实现: //牛顿方法.cpp
#include "NewtonsMethod.h"
#include "BaseFunctor.h"
#include <cmath>
const double NewtonsMethod::EPSILON = 1e-9;
const unsigned int NewtonsMethod::MAX_ITER = 30;
NewtonsMethod::NewtonsMethod(BaseFunctor *rhsIn,
BaseFunctor *rhsPrimeIn,
double x0In) :
rhs (rhsIn),
rhsPrime(rhsPrimeIn),
x0 (x0In)
{ }
NewtonsMethod::~NewtonsMethod() { }
bool NewtonsMethod::DetermineRoot(double &root)
{
// This is obviously not implemented
root = rhs(1.0) / rhsPrime(2.0);
return false;
}
以及我创建派生类实现的主要函数: // main.cpp
#include "BaseFunctor.h"
#include "NewtonsMethod.h"
#include <iostream>
#include <iomanip>
class fOfX : public BaseFunctor
{
double operator() (double x)
{
return x * x - 2.0;
}
};
class fPrimeOfX : public BaseFunctor
{
double operator() (double x)
{
return 2.0 * x;
}
};
int main()
{
double x0 = 2.0;
BaseFunctor *f = new fOfX();
BaseFunctor *fPrime = new fPrimeOfX();
NewtonsMethod newton(f, fPrime, x0);
double root = 0.0;
bool converged = newton.DetermineRoot(root);
if (converged)
{
std::cout << "SUCCESS: root == " << std::setprecision(16) << root << std::endl;
}
else
{
std::cout << "FAILED: root == " << std::setprecision(16) << root << std::endl;
}
delete f;
delete fPrime;
}
我尽量简短,如果太长,请见谅。基本上我得到错误:
g++ Main.cpp NewtonsMethod.cpp -o main
NewtonsMethod.cpp: In member function ‘bool NewtonsMethod::DetermineRoot(double&)’:
NewtonsMethod.cpp:29: error: ‘((NewtonsMethod*)this)->NewtonsMethod::rhs’ cannot be used as a function
NewtonsMethod.cpp:29: error: ‘((NewtonsMethod*)this)->NewtonsMethod::rhsPrime’ cannot be used as a function
我怎样才能解决这个问题,保持所需的功能或为各种需要的功能派生一个类?
谢谢
最佳答案
rhs
和 rhsPrime
是指针。您需要引用它们才能调用函数调用运算符。
(*rhs)(1.0) / (*rhsPrime)(2.0)
如果 rhs
和 rhsPrime
是必需的(即不能为 NULL)并且在 NewtonsMethod
对象具有构造函数后不能更改,您应该声明它们作为引用而不是指针。这也消除了取消引用它们以调用函数调用运算符的需要。
下面的例子展示了如何使用引用来引用仿函数。
class NewtonsMethod
{
public:
NewtonsMethod(BaseFunctor& rhsIn,
BaseFunctor& rhsPrimeIn,
double x0In);
~NewtonsMethod();
bool DetermineRoot(double &root);
private:
double x0;
BaseFunctor& rhs;
BaseFunctor& rhsPrime;
static const double EPSILON;
static const unsigned int MAX_ITER;
};
int main()
{
double x0 = 2.0;
fOfX f;
fPrimeOfX fPrime;
NewtonsMethod newton(f, fPrime, x0);
}
……或者……
int main()
{
double x0 = 2.0;
BaseFunctor *f = new fOfX();
BaseFunctor *fPrime = new fPrimeOfX();
NewtonsMethod newton(*f, *fPrime, x0);
// ... other code including delete for the functors
}
关于C++定义虚基类重载运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17460480/