I have some issues to find a relevant solution to my problem. I have to return some data from a class, and the type of data kind of depends on the class. My first solution was this :
class Base
{
virtual QVector<Data*> getData() const = 0;
};
class Derived : public Base
{
virtual QVector<DerviedData*> getData() const = 0;
};
But I know this is impossible, even if DerivedData extends Data, because of invalid covariant return types.
So I came up with another idea which implies template. What I did is I turned the Base class into a template class :
template<class T>
class Base
{
virtual QVector<T*> getData() const = 0;
}
And then I could write a Derived
constructor like that :
Derived::Derived() : Base<DerivedData>() {}
But know I have another problem. Suppose that I write another class, which has a method taking any Base class in parameters.
void Foo::doSomething(Base* b) {
b->getData();
}
This does not compile and says
invalid use of template-name 'Base' without an argument list
which I understand perfectly.
Supposing that my code will look like that :
DerivedClass1 d1;
DerivedClass2 d2;
DerivedClass3 d3;
this->doSomething(&d1);
this->doSomething(&d2);
this->doSomething(&d3);
What are my solutions here ? May I do something like "templating" the method doSomething ?
this->doSomething<DerivedData>(&d1);
With a protoype like
template<class T>
void doSomething(Base<T>* b);
Is that possible ? Is that a good way of thinking ? Coming from Java, I used to resolve such problems by using wildcards
abstract List<? extends Data> getData();
But I heard there is stricly speaking no such things in C++ (more or less simulable with such things as std::is_base_of
).
Thank you for your time.
You can let Derived::getData(
) return QVector<Data*>
. When you need to use it, find out if the pointers in QVector
is to Data
or DerivedData
, using dynamic_cast
or similar method.