Я пытаюсь написать набор общих классов математической утилиты (корневых искателей, интеграторов и т. Д.), Которые принимают при построении указатель на базовый класс, который определяет функцию, которую я хочу специфический алгоритм для работы. Базовый класс должен определять только виртуальный виртуальный интерфейс (абстрактное или стандартная тривиальная функциональность) type operator()(type inputArg)
, который может быть реализован пользователем по мере необходимости. Это позволит пользователю просто реализовать нужные функторы и выполнить необходимые вычисления. Мой м.в.э. ниже:C++ Определение перегруженного оператора виртуального базового класса
Это первый заголовок определяет абстрактный класс интерфейса
// 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
Это реализация решателя: // NewtonsMethod.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
Как я могу получить это разрешить сохранение требуемой функциональности или получения класса для различных нужных функций?
Благодаря
Спасибо! Развертывание их работы, хотя и является уродливым решением. Как взять их в качестве ссылок, поскольку я имею в виду их как объект BaseClass? Я не могу статически выделять их в основном, правильно? – JohnML
Я обновил свой ответ, чтобы включить пример использования ссылок. Конечно, вам все равно нужно убедиться, что объекты-функторы имеют время жизни, равное или большее, чем объект «NewtonsMethod». –
Большое спасибо за разъяснение. У меня никогда не было привязки класса к статически созданным объектам в качестве переменных-членов (только указатели (или значения ...)). Это работает по своему желанию и является более чистым, чем разыменование, а также новое/удаление. – JohnML