Student
Student

Reputation: 117

template inheritance and abstract class

I have 2 problems with the following classes. I got 2 errors: the first probably is an issue about inheritance among template classes, the other about initializing an abstract class when this class in fact is not abstract (see comments in the code)

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 T& _initialValue,
               const Interval<R>& _range,
               const T& _kappa,
               const T& _theta,
               const T& _sigma);

        CIRSDE();
        ~CIRSDE(){};

        T GetInitialValue();
        T GetDrift(const T& t, const T& r);
        T GetDiffusion(const T& t, const T& r);

};


template <typename T, typename R>
CIRSDE<T,R> :: CIRSDE(const T& _initialValue,
                  const Interval<R>& _range,
                  const T& _kappa,
                  const T& _theta,
                  const T& _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 T& t, const T& r)
{
     return kappa * (theta - r);
}

 template <typename T, typename R>
 T CIRSDE<T,R> ::  GetDiffusion(const T& t, const T& 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;
 }

Upvotes: 1

Views: 280

Answers (1)

Error 1:

 template <typename T, typename R>
 T CIRSDE<T,R> :: GetInitialValue()
 {
       return  initialValue;     // ERROR 1
       // undeclared identifier "initialValue"
 }

This is a problem with lookup. The identifier initialValue is not dependent on the template arguments and is thus resolved during the first pass before the actual types are substituted in and without checking in the base (the base is really not known until you substitute the types!)

You can solve it by qualifying as you did before SDE<T,R>::initialValue or by using this:

       return this->initialValue;

Error 2

CIRSDE<int, int> a (1, range, 3,3,3); //ERROR2
// variable CIRSDE<> is an abstract class

The problem is that the base has a couple of pure virtual functions for which you did not provide a definition in CIRSDE. In particular:

    virtual  T GetDrift() = 0;
    virtual  T GetDiffusion() = 0;

Note that the following, in the derived type, are not override as their signatures don't match:

    T GetDrift(const T& t, const T& r);
    T GetDiffusion(const T& t, const T& r);

Upvotes: 1

Related Questions