12
votes

Interface / Superclass pour collections / conteneurs en C ++

Je viens du monde de Java et je construis un petit programme C ++ pour le moment. J'ai un objet qui fait du travail et renvoie ensuite le résultat du travail comme une liste.

Maintenant un jour plus tard, j'ai changé le comportement de l'objet pour enregistrer les résultats dans un ensemble pour éviter les doublons dans le conteneur. Mais je ne peux pas simplement retourner le jeu car j'ai utilisé une liste pour l'interface dans la première fois. Y a-t-il une interface de conteneur commune que je peux utiliser pour spécifier l'interface de mon objet et oublier le type de conteneur que j'utilise en interne?

Pour le moment, je crée un ensemble ajoutant toutes les valeurs, puis créez Une liste de l'ensemble: xxx

semble un peu étrange.


0 commentaires

4 Réponses :


12
votes

L'ensemble de la bibliothèque standard de C ++ comprenant ses conteneurs est - contrairement à Java - non interface (héritage, polymorphisme) - mais à base d'efficacité (pour l'efficacité).

Vous pouvez créer une enveloppe polymorphe autour de votre collection, mais Ce n'est pas la solution C ++.

La solution la plus simple consiste simplement à simplifier le programme avec certains alias de type: xxx

Vous pouvez maintenant changer le Collection -TYPEDF sans avoir à changer d'autre chose. (Remarque: Si vous faites COLLECTION PUBLIC, l'utilisateur sera en mesure de renvoyer le type que vous avez utilisé explicitement)


0 commentaires

2
votes

De votre description, je pense que la réponse courte est non.

En général, lorsque je crée une forme de collection comme celle-ci, j'utiliserais normalement un typeEF pour spécifier le conteneur que j'utilise: P>

void foo (std::list<int> & list) {

  // ... fill the list

  list.sort ();
  list.unique (); 
}


0 commentaires

3
votes

Aucune interface n'existe. Au lieu de cela, vous utilisez généralement des modèles et dis simplement "Je me fiche de savoir quel type il est, tant que cela se comporte comme un conteneur".

supposer que votre fonction ressemble à ceci: P>

template <typename container_type>
void caller() {
  container_type result = DoStuff();
}


0 commentaires

12
votes

Le concept d'un conteneur est enbrodié par les itérateurs.
Comme vous avez vu un codage dur, un type de conteneur spécifique n'est probablement pas ce que vous voulez. Donc, faites vos itérateurs de retour de classe. Vous pouvez ensuite réutiliser les itérateurs conatiners.

class MyClass
{
    private:
        typedef  std::list<int>            Container;
    public:
        typedef  Container::iterator       iterator;
        typedef  Container::const_iterator const_iterator; 


        iterator        begin()        {return myData.begin();}
        const_iterator  begin() const  {return myData.begin();}

        iterator        end()          {return myData.end();}
        const_iterator  end()   const  {return myData.end();}

    private:
        Container   myData;
};


0 commentaires