#c #templates #inheritance #abstract-class
#c #шаблоны #наследование #абстрактный класс
Вопрос:
У меня 2 проблемы со следующими классами. Я получил 2 ошибки: первая, вероятно, связана с наследованием между классами шаблонов, другая — с инициализацией абстрактного класса, когда этот класс на самом деле не является абстрактным (см. Комментарии в коде)
some_header.h
template <typename T, typename R>
class SDE // abstract class
{
protected:
T drift, diffusion; // drift and diffusion terms
T initialValue;
Interval<R> range;
public:
virtual T GetInitialValue() = 0; // initial condition
virtual T GetDrift() = 0;
virtual T GetDiffusion() = 0;
virtual ~SDE();
};
#include "SDE.h"
#include <cmath>
template <typename T, typename R> // Cox, Ingersoll, Ross sde
class CIRSDE : public SDE<T,R>
{
private:
T kappa, theta, sigma;
public:
CIRSDE(const Tamp; _initialValue,
const Interval<R>amp; _range,
const Tamp; _kappa,
const Tamp; _theta,
const Tamp; _sigma);
CIRSDE();
~CIRSDE(){};
T GetInitialValue();
T GetDrift(const Tamp; t, const Tamp; r);
T GetDiffusion(const Tamp; t, const Tamp; r);
};
template <typename T, typename R>
CIRSDE<T,R> :: CIRSDE(const Tamp; _initialValue,
const Interval<R>amp; _range,
const Tamp; _kappa,
const Tamp; _theta,
const Tamp; _sigma)
{
kappa = _kappa;
theta = _theta;
sigma = _sigma;
SDE<T,R> :: initialValue = _initialValue;
SDE<T,R> :: range = _range;
}
template <typename T, typename R>
CIRSDE<T,R> :: CIRSDE()
{
kappa = 1;
theta = 1;
sigma = 1;
SDE<T,R> :: initialValue = 1;
SDE<T,R> :: range = Interval<R>(0,1);
}
template <typename T, typename R>
T CIRSDE<T,R> :: GetDrift (const Tamp; t, const Tamp; r)
{
return kappa * (theta - r);
}
template <typename T, typename R>
T CIRSDE<T,R> :: GetDiffusion(const Tamp; t, const Tamp; r)
{
return sigma * sqrt(r);
}
template <typename T, typename R>
T CIRSDE<T,R> :: GetInitialValue()
{
return initialValue; // ERROR 1
// undeclared identifier "initialValue"
}
main.cpp
#include "some_header.h"
int main()
{
Interval<int> range(0,5);
CIRSDE<int, int> a (1, range, 3,3,3); //ERROR2
// variable CIRSDE<> is an abstract class
return 0;
}
Комментарии:
1. Первая ошибка — это проблема с поиском зависимого имени (базовые классы, зависящие от параметров шаблона, не ищутся при использовании неквалифицированного имени). Используйте
SDE<T,R> :: initialValue
так же, как в конструкторе.2. Вторая ошибка, вероятно, заключается в том, что вы, похоже, пытаетесь переопределить виртуальные функции
GetDiffusion
иGetInitialValue
inCIRSDE
. Переопределение виртуальных функций требует использования точно такого же списка параметров и ковариантного возвращаемого типа. Т.Е. Вы не переопределяете эти функции, а скрываете функции базового класса с помощью новых, не связанных функций.3. В следующий раз, пожалуйста, предоставьте полный пример. Шаблон класса
Interval
здесь отсутствует.4. Хм. Я пытался понять, как вы разделили это на файлы, но для меня это не совсем имеет смысл. Не стесняйтесь исправить это. Обратите внимание, что шаблоны должны быть определены в заголовочных файлах (если вы явно не создаете их экземпляры или не специализируете их).
Ответ №1:
Ошибка 1:
template <typename T, typename R>
T CIRSDE<T,R> :: GetInitialValue()
{
return initialValue; // ERROR 1
// undeclared identifier "initialValue"
}
Это проблема с поиском. Идентификатор initialValue
не зависит от аргументов шаблона и, таким образом, разрешается во время первого прохода, прежде чем фактические типы будут заменены в базе и без проверки в базе (база действительно неизвестна, пока вы не замените типы!)
Вы можете решить эту проблему, выполнив квалификацию, как вы делали раньше SDE<T,R>::initialValue
, или используя this
:
return this->initialValue;
Ошибка 2
CIRSDE<int, int> a (1, range, 3,3,3); //ERROR2
// variable CIRSDE<> is an abstract class
Проблема в том, что в базе есть пара чисто виртуальных функций, для которых вы не предоставили определение CIRSDE
. В частности:
virtual T GetDrift() = 0;
virtual T GetDiffusion() = 0;
Обратите внимание, что следующие в производном типе не переопределяются, поскольку их подписи не совпадают:
T GetDrift(const Tamp; t, const Tamp; r);
T GetDiffusion(const Tamp; t, const Tamp; r);