Template Abstract Class C ++

0

Hello, I have the following problem. I have many functions that perform different operations, so I wanted to group this sharing with an interface (abstract class) of the Evaluable

type

Now as each function returns something different I thought I put something of the style.

+evaluar():void*

But it does not seem the most beautiful, so I implemented the following:

Evaluable.h

template <class T>
class Evaluable{
public:
    Evaluable();
    virtual ~Evaluable();
    virtual T evaluar()=0;
};

Evaluable.c

    template <typename T>
Evaluable<T>::Evaluable(){}

Therefore a derived class would be something of this style. Numb.h

class Number:public Evaluable<int>{
int numero;
public:
    Number(std::string cadena);
    ~Number();
    int evaluar();
};

But I miss the error:

Number.cpp:6: referencia a 'Evaluable<int>::Evaluable()' sin definir
Number.cpp:15: referencia a 'Evaluable<int>::~Evaluable()' sin definir

What I want is to have the possibility of having a list of Evaluables and call each one with evaluate ()

    
asked by user5431 14.04.2016 в 19:56
source

1 answer

0

The compiler is basically telling you that it finds neither the constructor's implementation nor the template's destructor. If you do not want to do anything in these functions you can do the following in C ++ 98:

template <class T>
class Evaluable{
public:
    Evaluable() {}
    virtual ~Evaluable() {}
    virtual T evaluar()=0;
};

Or, in C ++ 11 and later:

template <class T>
class Evaluable{
public:
    Evaluable() = default;
    virtual ~Evaluable() = default;
    virtual T evaluar()=0;
};

Even so, what I have explained to you would only be necessary if the class were inheritable ... which is not going to be the case. A limitation of the templates in C ++ is that they can not have abstract members (or pure virtual, as you prefer). On the other hand, they admit virtual members. This means that your "evaluate" solution will not work.

The solution you can use is to specialize the template to do what you want. In this case, the function does not need to be virtual :

template <class T>
class Evaluable{
public:
    T evaluar() { return T(); } // Implementación por defecto
};

template <>
class Evaluable<int>{
public:
    int evaluar()
    { /* implementación específica */ }
};

The problem with this solution is that the different specializations of template will not have a common inheritance. They are going to be independent classes. Of course, if we take into account that for a series of classes to inherit from a common interface they must have at least one method with exactly the same signature and in your case that will not be possible because evaluate will have different return values it seems obvious that this is not going to be a problem.

    
answered by 14.04.2016 / 22:09
source