2017-03-29 5 views
0

J'ai quelques problèmes pour trouver une solution pertinente à mon problème. Je dois retourner des données d'une classe, et le type de données dépend de la classe. Ma première solution était la suivante:Conteneurs C++, covariance et modèle

class Base 
{ 
    virtual QVector<Data*> getData() const = 0; 
}; 

class Derived : public Base 
{ 
    virtual QVector<DerviedData*> getData() const = 0; 
}; 

Mais je sais que cela est impossible, même si DerivedData Extends, en raison des types de retour covariant invalides.

Donc je suis venu avec une autre idée qui implique un modèle. Ce que je l'ai fait est que je tournais la classe de base dans une classe de modèle:

template<class T> 
class Base 
{ 
    virtual QVector<T*> getData() const = 0; 
} 

Et alors je pourrais écrire un constructeur Derived comme ça:

Derived::Derived() : Base<DerivedData>() {} 

Mais sais que j'ai un autre problème. Supposons que j'écrive une autre classe, qui a une méthode prenant n'importe quelle classe de base dans les paramètres.

void Foo::doSomething(Base* b) { 
    b->getData(); 
} 

Cela ne compile pas et dit

utilisation invalide du template-name 'base' sans une liste d'arguments

que je comprends parfaitement.

Supposant que mon code ressemblera que:

DerivedClass1 d1; 
DerivedClass2 d2; 
DerivedClass3 d3; 

this->doSomething(&d1); 
this->doSomething(&d2); 
this->doSomething(&d3); 

Quelles sont les solutions ici? Puis-je faire quelque chose comme "templating" la méthode doSomething?

this->doSomething<DerivedData>(&d1); 

Avec un protoype comme

template<class T> 
void doSomething(Base<T>* b); 

Est-ce possible? Est-ce une bonne façon de penser? En venant de Java, j'ai utilisé pour résoudre ces problèmes en utilisant des jokers

abstract List<? extends Data> getData(); 

Mais j'entendu dire qu'il parle stricly pas de telles choses en C++ (plus ou moins simulable avec des choses telles que std::is_base_of).

Nous vous remercions de votre temps.

+1

_Est-ce possible? _ Eh bien ... L'avez-vous essayé? –

+1

DerivedData hérite-t-il de Data? Alors ce n'est pas un problème. –

+0

@ AlgirdasPreidžius: Non, je n'ai pas essayé. Comme cela me semble étrange, je voulais savoir si c'était une meilleure solution, mais je vais essayer. –

Répondre

0

Vous pouvez laisser Derived::getData() retourner QVector<Data*>. Lorsque vous avez besoin de l'utiliser, découvrez si les pointeurs dans QVector est à Data ou DerivedData, en utilisant dynamic_cast ou une méthode similaire.