наследование шаблонов и абстрактный класс

#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 in CIRSDE . Переопределение виртуальных функций требует использования точно такого же списка параметров и ковариантного возвращаемого типа. Т.Е. Вы не переопределяете эти функции, а скрываете функции базового класса с помощью новых, не связанных функций.

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);