У меня есть некоторые проблемы, чтобы найти соответствующее решение моей проблемы.
Я должен вернуть некоторые данные из класса, и тип данных зависит от класса.
Моим первым решением было следующее:
class Base
{
virtual QVector<Data*> getData() const = 0;
};
class Derived : public Base
{
virtual QVector<DerviedData*> getData() const = 0;
};
Но я знаю, что это невозможно, даже если DerivedData расширяет данные из-за недопустимых ковариантных типов возвращаемых данных.
Таким образом, я пришел с другой идеей, которая подразумевает шаблон. Я превратил базовый класс в шаблонный класс:
template<class T>
class Base
{
virtual QVector<T*> getData() const = 0;
}
И тогда я мог бы написать Derived
конструктор так:
Derived::Derived() : Base<DerivedData>() {}
Но знай, у меня есть другая проблема. Предположим, что я пишу другой класс, у которого есть метод, принимающий любой базовый класс в параметрах.
void Foo::doSomething(Base* b) {
b->getData();
}
Это не компилируется и говорит
недопустимое использование имени шаблона ‘Base’ без списка аргументов
что я прекрасно понимаю.
Предположим, что мой код будет выглядеть так:
DerivedClass1 d1;
DerivedClass2 d2;
DerivedClass3 d3;
this->doSomething(&d1);
this->doSomething(&d2);
this->doSomething(&d3);
Каковы мои решения здесь? Могу ли я сделать что-то вроде «шаблонизации» метода doSomething?
this->doSomething<DerivedData>(&d1);
С прототипом вроде
template<class T>
void doSomething(Base<T>* b);
Это возможно ? Это хороший способ мышления?
Исходя из Java, я использовал для решения таких проблем с использованием подстановочных знаков
abstract List<? extends Data> getData();
Но я слышал, что в C ++ строго не существует таких вещей (более или менее подражающих таким вещам, как std::is_base_of
).
Спасибо за ваше время.
Вы можете позволить Derived::getData(
) вернуть QVector<Data*>
, Когда вам нужно его использовать, выясните, есть ли QVector
это к Data
или же DerivedData
, с помощью dynamic_cast
или похожий метод.
Других решений пока нет …