Question

En fait, j'ai une question de conception ici. C’est très simple, mais l’essentiel est:

J'ai une classe C ++ qui a un vecteur STL déclaré en tant que membre privé. Mais les clients de cette classe doivent parcourir ce vecteur.

En C #, nous avons une instruction très pratique, le rendement, qui vous permet d'écrire une fonction renvoyant un IEnumerable et qu'elle "donne" vous un bon moyen de parcourir un conteneur privé à l'intérieur de cette classe.

J'essaie simplement de trouver une solution élégante pour C ++ au lieu d'utiliser des méthodes telles que GetValue (int idx).

Des suggestions?

Exemple:

class Fat
{
   public:
      Fat();
   // some code here ...

   private:
      void LoadSectors(SECT startPoint);
      std::vector<SECT>sectors;

};

class Storage
{
   public:
      Storage(string CompoundFile);

      //For example, this method will receive a ref to my fat system and iterate over
      //the fat array in order to read every sector. 
      LoadStrem(Fat& fat);

};

Cet exemple est loin d'être simple.

Était-ce utile?

La solution

Il n'y a pas de sucre syntaxique en C ++ analogue à yield en C #. Si vous souhaitez créer une classe, dont les instances doivent être itérables de la même façon que les collections STL en stock, vous devez alors implémenter un itérateur pour votre classe et l'exposer sous la forme :: iterator sur votre type. et fournit les fonctions membres begin () et end () .

Autres conseils

Vous pouvez créer une fonction d'accesseur qui renvoie une référence (ou de préférence, une référence) au vecteur ou créer un code begin () et end () . fonctions qui renvoient les itérateurs de vecteurs appropriés.

Cela fait toujours mal lorsque vous devez publier les entrailles de votre classe ...

Vous pourrez peut-être le résoudre en fournissant des algorithmes comme le fait stl: fournissez une fonction foreach sur l'interface de l'objet.

class S { 
   std::vector<int> v;

public:
   //... and some methods to populate the vector

   template< typename F > F& foreach( F& f ) { 
      return std::for_each( v.begin(), v.end(), f );
   }

};

De cette façon, la classe reste «fermée», mais vous avez la flexibilité dont vous avez besoin. Vous pouvez également ajouter une fonction copy et peut-être un transformer ; ce sont ceux dont j'ai le plus souvent besoin.

Laissez votre classe exposer les itérateurs.

class Fat
{
   public:
    typedef std::vector<SECT>::iterator iterator;

    iterator begin() { return sectors.begin(); }
    iterator end() { return sectors.end(); }

      Fat();
   // some code here ...

   private:
      void LoadSectors(SECT startPoint);
      std::vector<SECT>sectors;

Ensuite, le code environnant peut parcourir les éléments du vecteur librement, par le biais d'une paire d'itérateurs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top