2010-07-29 2 views
2

Je viens de lire un article sur le modèle de modèle curieusement récurrent. Et vous pouvez l'utiliser pour simuler des fonctions virtuelles avec des modèles.Conception pour utiliser toutes les sous-classes ensemble dans un conteneur en C++

Par exemple:

template<class T> 
struct A 
{ 
    void func() { static_cast<T*>(this)->func(); } 
}; 

struct B : public A<B> 
{ 
    void func() { cout << "B" << endl; } 
};` 

Cependant, si nous avons beaucoup de sous-classes de A et que vous voulez les mettre tous dans le vecteur, par exemple, vector<A*> ce n'est pas possible lorsque vous utilisez des modèles, et vous devez utiliser polymorphisme normal avec des fonctions virtuelles dans la classe de base.

Quelle serait une suggestion de conception pour résoudre ce problème? Parce que je veux utiliser des modèles, mais aussi être capable d'utiliser toutes les sous-classes ensemble dans un conteneur.

Répondre

5

Vous pouvez le faire:

class NonTemplateBase 
{ 
}; 

template<class T> 
struct A : public NonTemplateBase 
{ 
    void func() { static_cast<T*>(this)->func(); } 
}; 

puis créer un vecteur de pointeurs vers NonTemplateBase (à savoir std::vector<NonTemplateBase *>).

Cependant, j'imagine que vous voulez pouvoir appeler ou d'autres fonctions membres sur les objets de votre vecteur - et vous voulez que ces appels appellent polymorphiquement la fonction membre correcte dans la classe dérivée. Cela ne fonctionnera pas car le modèle de modèle curieusement récurrent vous permet uniquement de faire statique (polymorphisme de compilation). Si vous voulez un polymorphisme d'exécution, vous devez utiliser des fonctions virtuelles.

+0

+1: me battre sur le polymorphisme d'exécution – onof

1

Définissez une classe de base abstraite sans modèle pour votre classe de modèle. Utilisez la classe de base pour travailler avec des conteneurs.

0

Tous vos modèles implémentent une interface commune et créent un vecteur de pointeurs ou de références à cette interface.

class Icommon //interface 
{ 
public: 
    virtual void print() = 0; 
}; 

template <class T> 
class MyCommon : public Icommon 
{ 
    T obj; 

public: 
    MyCommon(T o):obj(o) {} 

    void print() {cout << obj;} 
}; 

main() 
{ 
    MyCommon<int> i(1); 
    MyCommon<char> c('t'); 

    vector<Icommon *> commonVec; 

    commonVec.push_back(&i); 
    commonVec.push_back(&c); 
}