Permitir que la clase derivada implemente una única función virtual pura de la clase abstracta base

Is it possible to have a abstract base class with a number of pure virtual functions:

template <typename T, typename U = NullType, typename V = NullType>
class Functor { 
public:
    virtual ~Functor() {}

    virtual T operator()() = 0;
    virtual T operator()(U arg1) = 0;
    virtual T operator()(U arg1, V arg2) = 0;
};

And then have a derived class only implement one of these functions?

p.ej

class Test : public Functor<void> {
public:
    void operator()() {
        std::cout << "Called Test::operator()" << std::endl;
    }
};

The reason I have a base Functor class is so that I can store functors in a vector.

preguntado el 28 de agosto de 11 a las 03:08

(Assuming "derived" here means "most derived, concrete".) Why would it be? The whole point of pure virtual functions is that this is not allowed! -

3 Respuestas

Yes, it's possible. But the derived class will still be abstract.

Respondido 28 ago 11, 07:08

Yes, that's possible. However, that means that the derived class itself is still abstract and cannot be instantiated, and you need to derive further from it until you've defined all the virtual functions.

Respondido 28 ago 11, 07:08

No, that's not possible. What if you called T operator()(U) en un Test* and it hadn't implemented it? You'll have to eventually have a class implement all of them (or inherit from one or more classes that implement each of them) to instantiate it.

You can leave any number of virtual functions undefined, but if you do, your class won't be instantiatable because it's still abstract. You'll have to have another class inherit from it and define those undefined functions and instantiate that.

tl;dr: To instantiate a class, somewhere in its class hierarchy all virtual functions must have a definition.

Respondido 28 ago 11, 07:08

I was hoping that if the derived class only implemented one of the functions, the others would be considered undefined for that class. - ProtoSphere

@Protosphere that wouldn't be good, because you can pass around Test<...>*s como Functor<T>*s. So you can't tell what type it is, and the compiler can't follow your classes around at compile time and make sure you don't call an undefined virtual method on a class instance which hasn't defined it. So you have to implement all of them. - Seth Carnegie

So I guess the only way to achieve the behaviour that I want would be to have separate base classes such as Functor0, Functor1, Functor2 etc. that declare an operator() with a set amount of arguments. - ProtoSphere

@Proto yes, that's correct. Then you know how many arguments your Functor takes when you accept it as an argument. One possibility is to declare a template<unsigned int NumArgs> class Functor; and write specializations for 1, 2, 3, 4, 5, etc arguments, then have those take their respective numbers of arguments to operator(). - Seth Carnegie

@Proto como este, or you could always deduce the number of parameters by the number of template type arguments como este - Seth Carnegie

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.