2010-07-30 10 views
1

Ma principale catégorie de projets est classe basé sur un modèle, a déclaré avec:membres Accès de classe basé sur des modèles instanciés avec différents arguments de modèle

template<int dim, typename typ> 

dim est le nombre de dimensions (2 ou 3), et typ est type de données à virgule flottante (float ou double). Sur la base de ces paramètres, les instances de cette classe ont leurs membres de type spécifique et les vecteurs (math) ont dim nombre de composants. Donc les instances peuvent différer sur les types de membres, et leurs fonctions diffèrent sur les types de paramètres, mais elles ont toutes la même fonction ... ce qui peut être fait à l'exécution, c'est-à-dire accéder génériquement aux instances de cette classe créées avec différents arguments de modèle ???

+0

Quel est le problème ici? Pouvez-vous donner des exemples de comment vous vous attendez à appeler ces objets? Je soupçonne que vous n'avez pas besoin de la méthode de @Tyler McHenry (c'est correct, juste peut-être trop). Je suggère de définir la classe avec les méthodes et les membres dont vous avez besoin, et revenez nous quand vous avez quelque chose qui ne compilera pas :-) "template structure X {void f (type t);}; " –

Répondre

3

C'est exactement ce que l'héritage est pour. Vous créez une commune, non-modèle, classe de base virtuelle pure qui définit l'interface utilisée par tous vos modèles, par exemple:

class Base { 

    public: 

    virtual ~Base() {}; 

    virtual void foo() = 0; 

    virtual int bar(int param) = 0; 

    // Etc, for whatever other methods you want 
}; 

Ensuite, vous tirez votre modèle de celui-ci:

template<int dim, typename typ> 
class Dervied : public Base 
{ 
    public: 

    virtual ~Derived(); 

    virtual void foo(); 

    virtual int bar(int param); 

    // Etc, for whatever other methods you want 

    private: 

    std::vector<typ> data; 
}; 

Et bien sûr, implémentez les méthodes pour le modèle Derived. Ensuite, vous pouvez accéder à n'importe quelle instanciation de Derived via un pointeur ou une référence à Base. Par exemple:

void callFoo(const Base& b) 
{ 
    b.foo(); 
} 

int main() 
{ 
    Derived<3,float> d_f3; 
    Derived<2,double> d_d2; 

    callFoo(d_f3); 
    callFoo(d_d2); 

    return 0; 
} 

Il semble de votre description comme il peut y avoir des méthodes qui sont en commun entre tous les instanciations de Derived, mais certains qui dépendent des paramètres du modèle, par exemple

void addNumber(typ number); 

Dans ce cas, vous ne pouvez pas tirer cette fonction vers le haut dans Base, car il ne serait pas logique d'appeler cette méthode sur un Derived<n,float>. S'il y a des fonctions qui dépendent du type et certains qui dépendent du nombre, vous pouvez créer des classes de base encapsuler ces idées, comme ceci:

class Base 
    { /* All methods independent of template parameters */ }; 

template <int dim> DimBase : virtual public Base 
    { /* All methods dependent only on the dimension parameter */ }; 

template <typename typ> TypBase : virtual public Base 
    { /* All methods dependent only on the type parameter */ }; 

template<int dim, typename typ> 
    Derived : public DimBase<dim>, public TypBase<typ> 
    { /* All methods */ }; 

Cela vous permettra d'appeler une méthode indépendante en utilisant un Base pointeur ou référence, pour appeler toute méthode dépendante de la dimension à l'aide d'un pointeur ou d'une référence DimBase<n> et de toute méthode dépendant du type utilisant un pointeur ou une référence TypBase<T>.

Notez que dans ce qui précède, il est souhaitable que Base, TypBase et DimBase tous être des classes abstraites (contenant au moins une méthode virtuelle inappliquées), et il est essentiel que TypBase et DimBase Hériter de Base à l'aide virtual public au lieu de juste public, sinon vous obtenez le "dreaded diamond"

+0

Merci Tyler pour la réponse. L'héritage simple n'est pas un problème, le plus gros problème que j'ai est les paramètres de fonction qui dépendent de la dimension et du type, par ex. vec . Et eux ? –

+0

La deuxième partie de ma réponse traite de la façon dont vous pouvez obtenir un comportement polymorphe pour les méthodes qui dépendent de la dimension ou du type. Les méthodes qui dépendent de * both * dimension et de type doivent être définies dans la classe feuille et ne peuvent pas être utilisées de manière polymorphe. Pensez-y: si les arguments d'une méthode dépendent à la fois de la dimension et du type d'une classe, comment pourriez-vous espérer appeler cette même méthode sur un objet d'une classe avec des dimensions et des types différents? Une telle chose n'aurait aucun sens. –

Questions connexes