J'ai un conteneur personnalisé qui est implémenté de deux manières différentes, mais avec une seule interface. quelque chose comme ça. Ce dont j'ai besoin, c'est d'une interface unifiée à Iterator, de sorte que je puisse l'utiliser dans la classe de base. Des idées ?Iterator pour un conteneur personnalisé avec des classes dérivées
Répondre
J'ai déjà rencontré ce problème auparavant. Bien qu'il existe des moyens de résoudre votre problème, vous devriez abandonner l'idée d'une classe de base vectorielle. Ce que vous devriez probablement faire à la place, c'est imiter la façon dont le conteneur STL C++ est conçu.
La liste STL est constituée de concepts plutôt que de classes de base. Un std::vector
est un modèle du concept Container
, mais n'hérite pas d'une classe de base Container
. Un concept est un ensemble d'exigences auxquelles tout modèle du concept doit adhérer. Voir page this pour les exigences pour Container
par exemple.
Les exigences pour Container
Etat, par exemple que vous typedef le type de contenu du récipient comme value_type
et typedef itérateurs comme iterator
et const_iterator
. En outre, vous devez définir les fonctions begin()
et end()
renvoyant des itérateurs, et ainsi de suite.
Vous devrez ensuite modifier les fonctions qui fonctionnent sur votre classe de base Vector
pour opérer à la place sur toute classe qui respecte les exigences imposées par le concept. Cela peut être fait en rendant les fonctions modélisées. Vous ne devez pas nécessairement vous en tenir aux concepts utilisés par la STL, vous pouvez aussi bien préparer les vôtres. S'en tenir aux concepts tels qu'ils sont définis dans la STL a l'avantage supplémentaire que les algorithmes STL (std::sort
par exemple) peuvent fonctionner sur vos conteneurs.
Exemple rapide:
class VectorImplA
{
public:
typedef VectorImplAIterator iterator;
iterator begin();
iterator end();
};
class VectorImplB
{
public:
typedef VectorImplBIterator iterator;
iterator begin();
iterator end();
};
template <typename VectorConcept>
void doSomeOperations(VectorConcept &container)
{
VectorConcept::iterator it;
it = container.begin();
}
int main()
{
VectorImplA vecA;
VectorImplB vecB;
doSomeOperations(vecA); // Compiles!
doSomeOperations(vecB); // Compiles as well!
}
En prime, pour répondre à la question initiale, pensez à la conception suivante (je ne voudrais pas aller de cette façon si!):
struct IteratorBase
{
virtual void next() = 0;
};
struct IteratorA : IteratorBase
{
void next() {};
};
struct IteratorB : IteratorBase
{
void next() {};
};
class Iterator
{
IteratorBase *d_base;
public:
void next() { d_base->next(); }
};
Une possibilité consiste à utiliser une classe de modèle pour votre conteneur, avec le conteneur de données privé en tant que paramètre. De cette façon, l'itérateur peut être défini dans la classe indépendamment du conteneur de données.
Je ne suis pas sûr si c'est assez "unifié" pour ce dont vous avez besoin.
je faisais face à la même problème avant. Je solution # 2 avec une légère modification dans la définition de la classe Iterator
class Iterator :public boost::iterator_facade<Iterator,element_type, forward_traversal_tag>
{
...
}
De cette façon, j'ai pu utiliser des algorithmes de STL avec mes conteneurs.
- 1. Visualisation des classes dérivées en C#
- 2. Qt Stylesheets avec des classes dérivées
- 3. Sérialisation XML des classes dérivées
- 4. Iterator personnalisé en C++
- 5. STL iterator avec modèle personnalisé
- 6. Comment interroger un conteneur d'entités Entity Framework pour les objets de classes d'entités dérivées?
- 7. Classes dérivées et singleton
- 8. Condition de conteneur personnalisé pour travailler avec Qt's foreach
- 9. C++ modèle coulée avec les classes dérivées
- 10. Déclaration des Enums dans les classes dérivées
- 11. Classes dérivées UIscrollview
- 12. SetUp dans les classes dérivées avec NUnit?
- 13. vtables pour les classes dérivées, concrètes,
- 14. conteneur personnalisé
- 15. CTI RTTI et classes dérivées
- 16. Conteneur de nommage personnalisé pour ASP.NET GridView?
- 17. Héritage multiple de deux classes dérivées
- 18. Surcharge des constantes dans les classes dérivées en C#
- 19. Classes dérivées C#, résolution de surcharge
- 20. Lecteurs/écrivains et persistance découplée des classes dérivées
- 21. Classes Java dérivées de Hibernate pour les tables
- 22. Contrôle de conteneur personnalisé
- 23. Problèmes conceptuels avec Iterator
- 24. C++ Boost sérialisation sérialisation templated classes dérivées
- 25. La duplication ennuyeuse dans les classes dérivées
- 26. Les classes dérivées sont-elles considérées comme des amis?
- 27. Design Pattern: interface uniforme pour les classes dérivées partiellement supportées
- 28. C#: Héritant membres statiques séparés pour les classes dérivées
- 29. Options limitées pour accéder aux événements dans les classes dérivées?
- 30. C#: config XML lecture manuellement pour les classes dérivées
+1 bien que je n'utiliserais certainement PAS une opération 'next', mieux vaut respecter les conventions habituelles pour l'interopérabilité avec STL. –
Merci pour les réponses. J'ai déjà implémenté # 1, qui a été décrit ci-dessus. Le problème avec cela est que je ne peux pas avoir de polymorphisme d'exécution. c'est-à-dire, dériver VectorImplA et VectorImplB à partir du vecteur de classe de base et utiliser Vector * pour opérer sur les classes dérivées. Ai-je raison ? – Surya