2009-11-30 6 views
1

En fait, j'ai une question de conception ici. C'est très simple mais le point est:Rendement de C# à C++, traitant des conteneurs

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, que dans de tels cas, vous écrivez une fonction retournant un IEnumerable et cela vous "cède" une manière agréable d'itérer sur un conteneur privé à l'intérieur de cette classe. J'essaye juste de trouver une solution élégante pour C++, au lieu d'employer des méthodes comme 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); 

}; 

Ceci est par exemple bien simple.

+0

Qu'est-ce qui est si inélégant à propos de GetValue (index)? –

+0

@Ed: que vous êtes alors lié pour toujours à un conteneur indexable. Le code client n'a pas besoin de savoir comment les éléments sont contenus. – xtofl

+0

Il y a un petit exemple maintenant – Andres

Répondre

6

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

+2

Le vecteur implémente déjà un itérateur. Vous pouvez simplement faire 'typedef vector :: const_iterator const_iterator;' et (peut-être) 'typedef vector :: itérateur itérateur;' – UncleBens

4

Vous pouvez créer une fonction d'accès qui renvoie une référence (ou de préférence une référence constante) au vecteur, ou vous pouvez créer des fonctions d'accès begin() et end() qui renvoient les itérateurs vectoriels appropriés.

2

Il fait toujours mal quand vous avez besoin de publier les entrailles de votre classe ...

Vous pouvez être en mesure de le résoudre en fournissant des algorithmes comme stl ne: fournir une fonction foreach sur l'interface de l'objet. 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 transform; ce sont ceux dont j'ai le plus besoin.

+0

Il peut y avoir des raisons similaires de publier les "entrailles" comme 'std :: vector' publie ses" inards "- c'est-à-dire, il pourrait s'agir essentiellement d'une classe conteneur qui passe juste pour utiliser un' std :: vector' comme type sous-jacent. P.S L'exposition du contenu du vecteur n'expose pas le vecteur lui-même. – UncleBens

+1

Euh, ce n'est pas ce que fait la STL. Bien au contraire. Ce que le STL * ne fait pas, c'est coupler le conteneur et l'algorithme d'itération. – jalf

+0

@jalf: vous avez raison: cela signifierait 'vector.foreach (...)'.Je voulais dire _algorithmes_ comme le fait stl. – xtofl

1

Laissez votre classe exposer des itérateurs. Ensuite, le code environnant peut traverser librement les éléments du vecteur, à travers seulement une paire d'itérateurs.