OVH Cloud OVH Cloud

iterateur membre, constant

7 réponses
Avatar
Nicolas Aunai
salut,


j'ai la classe suivante :

class C_Coup
{
private:
vector<string> tab;

public:

vector<string>::iterator iter;
vector<string>::const_iterator citer;
vector<string>::iterator iter_fin;
vector<string>::const_iterator citer_fin;
C_Coup();
int indice(const string s);
};


j'ai pas envie que l'utilisateur touche a mon vector, donc je le mets
en private, je lui donne accès a des iterator pour qu'il puisse se
déplacer dans le vector.

j'ai sur ceci, quelques questions :

est-il possible de coder un objet qui serai constant mais qui
proposerai des iterator sur ses membres ? avec le peu de connaissances
que j'ai je dirais que non car objet constant implique iterator membre
constant implique iterator inutilisable ... ??

la chose suivante est-elle possible ?

class C_Coup
{
private:
vector<string> tab;

public:

typedef vector<string>::iterator iter;
typdef vector<string>::const_iterator citer;
typedef vector<string>::iterator iter_fin;
typdef vector<string>::const_iterator citer_fin;
C_Coup();
int indice(const string s);
};

si oui, dans quelles conditions puis-je utiliser mes nouveaux types ?

1) dans le codage de mes méthodes ?

2) dans toute fonction utilisant un objet C_Coup ?

autre question, celle ci relève un peu plus de la technique de
programmation avec ces outils, est-ce que ce genre de classe est une
bonne méthode pour restreindre l'accès a un tableau en laissant
possible des manipulations dessus ?

--
Nico,
http://astrosurf.com/nicoastro
messenger : nicolas_aunai@hotmail.com

7 réponses

Avatar
Benoit Rousseau
Nicolas Aunai wrote:
salut,


j'ai la classe suivante :

class C_Coup
{
private:
vector<string> tab;

public:

vector<string>::iterator iter;
vector<string>::const_iterator citer;
vector<string>::iterator iter_fin;
vector<string>::const_iterator citer_fin;
C_Coup();
int indice(const string s);
};


j'ai pas envie que l'utilisateur touche a mon vector, donc je le mets en
private, je lui donne accès a des iterator pour qu'il puisse se déplacer
dans le vector.

j'ai sur ceci, quelques questions :

est-il possible de coder un objet qui serai constant mais qui proposerai
des iterator sur ses membres ? avec le peu de connaissances que j'ai je
dirais que non car objet constant implique iterator membre constant
implique iterator inutilisable ... ??
Ton message est un peu flou...

Je ne comprends pas ce que tu veux faire...

Pourquoi est ce que tu ne créer pas deux méthodes qui retourne un
const_it pointant sur begin() et end() ?
const_it indique que l'objet pointé par l'itérateur est constant, pas
que l'itérateur est constant...

Tu veux juste réduire l'interface du vecteur ? C'est ca ?

Pourquoi ne pas faire :

class C_Coup {
protected:
vector<string> tab;
public:
typedef vector<string>::const_iterator citer;
citer begin() { return tab.begin(); }
citer end() { return tab.end(); }
}; //Code non testé, juste pour l'idée

Un utilisateur pourrait alors y acceder comme un vector normal...
C_Coup c;
for( C_Coup::citer it = c.begin(); it != c.end() ; ++ it )
//Code

Mais il faut résoudre le problème de l'initialisation...




--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/

Avatar
Thomas Abbé
j'ai la classe suivante :

class C_Coup
{
private:
vector<string> tab;

public:

vector<string>::iterator iter;
vector<string>::const_iterator citer;
vector<string>::iterator iter_fin;
vector<string>::const_iterator citer_fin;
C_Coup();
int indice(const string s);
};


j'ai pas envie que l'utilisateur touche a mon vector, donc je le mets
en private, je lui donne accès a des iterator pour qu'il puisse se
déplacer dans le vector.


hm, c pas du tt complique, tu trouves pas? tu as mnt 4 variables (les
iterateurs) au lieu d'une seul!
si tu as tjours une vue d'ensemble c bon ;)
en plus, pour un vector, tu nas pas besoin dutiliser des iterateurs.

for (i = 0; i < tab.size(); i++)
{
cout << tab[i].c_str() << endl;
}

si tu veux pas que lutilisateur ne voit pas ton vector, fais comme ca:

private:
vector<string> tab;
public:
string get(int i)
{
... //verifications
return tab[i];
}

j'ai sur ceci, quelques questions :

est-il possible de coder un objet qui serai constant mais qui
proposerai des iterator sur ses membres ? avec le peu de connaissances
que j'ai je dirais que non car objet constant implique iterator membre
constant implique iterator inutilisable ... ??

la chose suivante est-elle possible ?

class C_Coup
{
private:
vector<string> tab;

public:

typedef vector<string>::iterator iter;
typdef vector<string>::const_iterator citer;
typedef vector<string>::iterator iter_fin;
typdef vector<string>::const_iterator citer_fin;
C_Coup();
int indice(const string s);
};
si oui, dans quelles conditions puis-je utiliser mes nouveaux types ?

1) dans le codage de mes méthodes ?



typedef vector<string>::iterator iter;
typdef vector<string>::const_iterator citer;
typedef vector<string>::iterator iter_fin;
typdef vector<string>::const_iterator citer_fin;

cela est possible, mais je les declarerais pas ds la classe. ce ne sont plus
des variables, slt des "synonymes"

ds ta classe tu devrais donc ecrire:
public:
iter it;
citer cit;
iter_fin itf;
citer_fin citf;

it, cit, itf, citf sont mnt les membres de la calsse!
mais comme jai viens de dire ce nest pas une bonne idee dutiliser des
iterateurs ds ce cas la.


2) dans toute fonction utilisant un objet C_Coup ?


si tu declares les types ds un fichier .h, et tu fais un #include, tu peux
utiliser les definitions nimporte ou!


autre question, celle ci relève un peu plus de la technique de
programmation avec ces outils, est-ce que ce genre de classe est une
bonne méthode pour restreindre l'accès a un tableau en laissant
possible des manipulations dessus ?


voir ci dessus. c une bonne idee, mais c utile de travailler avec des
methodes GetX(..) et SetY(..).

thomas

Avatar
Nicolas Aunai


Ton message est un peu flou...


je sais, j'm'en excuse, mais c'est parce que ça l'est aussi dans ma
tête :)

Je ne comprends pas ce que tu veux faire...

Pourquoi est ce que tu ne créer pas deux méthodes qui retourne un const_it
pointant sur begin() et end() ?


pas bête, je n'y avait même pas pensé

const_it indique que l'objet pointé par l'itérateur est constant, pas que
l'itérateur est constant...


oui je sais, mais si l'objet dont l'iterateur est constant, alors
l'iterateur lui même devient difficilement exploitable, il est..
constant !

Tu veux juste réduire l'interface du vecteur ? C'est ca ?


euh en gros oui, c'est ça.
en fait j'ai dans mon programme plusieurs endroits où j'utilise un
vecteur identique, et avec les mêmes opérations dessus, j'ai donc
décidé de créer un objet "C_COUP" qui contient mon vector, et des
iterateur pour le manipuler

Pourquoi ne pas faire :

class C_Coup {
protected:
vector<string> tab;
public:
typedef vector<string>::const_iterator citer;
citer begin() { return tab.begin(); }
citer end() { return tab.end(); }
}; //Code non testé, juste pour l'idée


c'est vrai, c'est plus malin, c'est sans doute le manque
d'expérience...

Un utilisateur pourrait alors y acceder comme un vector normal...
C_Coup c;
for( C_Coup::citer it = c.begin(); it != c.end() ; ++ it )
//Code

Mais il faut résoudre le problème de l'initialisation...


l'initialisation est faite par le constructeur, l'objet coup n'est pas
sensé bouger, il n'est là que pour être comparé a d'autres et servir de
références pour d'autres objets... d'ou ma première volonté de le
définir comme constant.

--
Nico,
http://astrosurf.com/nicoastro
messenger :

Avatar
Benoit Rousseau
Nicolas Aunai wrote:


oui je sais, mais si l'objet dont l'iterateur est constant, alors
l'iterateur lui même devient difficilement exploitable, il est.. constant !

Non, const_iterator n'est pas "const iterator". L'itérateur n'est pas

constant, mais la valeur qu'il contient est constante : il y a une
grosse différence...



Tu veux juste réduire l'interface du vecteur ? C'est ca ?



euh en gros oui, c'est ça.
en fait j'ai dans mon programme plusieurs endroits où j'utilise un
vecteur identique, et avec les mêmes opérations dessus, j'ai donc décidé
de créer un objet "C_COUP" qui contient mon vector, et des iterateur
pour le manipuler
En fait, créer des itérateurs dans ta classe limite le nombre d'accès

que tu peux y faire... C'est un peu dommage... Tu ne pourras pas
parcourrir ton vecteur pour comparer tous les éléments entre eux par
exemple.



--
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/


Avatar
kanze
Nicolas Aunai ç wrote in message
news:...

j'ai la classe suivante :

class C_Coup
{
private:
vector<string> tab;

public:

vector<string>::iterator iter;
vector<string>::const_iterator citer;
vector<string>::iterator iter_fin;
vector<string>::const_iterator citer_fin;
C_Coup();
int indice(const string s);
};

j'ai pas envie que l'utilisateur touche a mon vector, donc je le mets
en private, je lui donne accès a des iterator pour qu'il puisse se
déplacer dans le vector.


Et pour qu'il puisse modifier ton vecteur. D'ailleurs, pourquoi des
variables publiques. Je verrais plutôt quelque chose du genre :

class Coup
{
public:
typedef std::vector< std::string >::const_iterator
iterator ;

iterator begin() const
{
return myTab.begin() ;
}
iterator end() const
{
return myTab.end() ;
}
private:
std::vector< std::string >
myTab ;
} ;

On pourrait imaginer même à en faire une collection de Coup ; à y mettre
toute l'interface habituelle d'une séquence, par exemple.

j'ai sur ceci, quelques questions :

est-il possible de coder un objet qui serai constant mais qui
proposerai des iterator sur ses membres ?


Certainement.

avec le peu de connaissances que j'ai je dirais que non car objet
constant implique iterator membre constant implique iterator
inutilisable ... ??


Pas du tout. L'important, c'est que l'itérateur n'est pas membre de la
collection. Donc, même si la collection est constante, l'itérateur ne
l'est pas forcement. (En revanche, il doit être un const_iterator, c-à-d
grosso modo un itérateur dont l'opérateur * renvoie une référence const,
et non une simple référence, de façon à ce que l'utilisateur ne peut pas
modifier ta collection à travers l'itérateur.)

la chose suivante est-elle possible ?

class C_Coup
{
private:
vector<string> tab;

public:

typedef vector<string>::iterator iter;
typdef vector<string>::const_iterator citer;
typedef vector<string>::iterator iter_fin;
typdef vector<string>::const_iterator citer_fin;
C_Coup();
int indice(const string s);
};

si oui, dans quelles conditions puis-je utiliser mes nouveaux types ?


Ajoute des fonctions qui les renvoient, c'est tout.

Deux choses, cependant :

- Si tu veux que ta classe soit non modifiable, même les iterator (et
non seulement les const_iterator) doivent être les typedef à
std::vector< string >::const_iterator.

- Le nom consacré pour les itérateurs, c'est iterator, et non iter. Ça
a de l'importance dès que tu veux utiliser des templates -- si ton
type s'appelle iterator, tu peux écrire un template qui marche à la
fois avec C_Coup et avec les collections standard.

1) dans le codage de mes méthodes ?


Comme partout ailleurs, dans C_Coup, tu obtiens les itérateurs de tab.
Que tu peux rendre publique en les renvoyant d'une fonction, on non,
comme bon te semble.

2) dans toute fonction utilisant un objet C_Coup ?

autre question, celle ci relève un peu plus de la technique de
programmation avec ces outils, est-ce que ce genre de classe est une
bonne méthode pour restreindre l'accès a un tableau en laissant
possible des manipulations dessus ?


Plutôt, oui. Je m'en sers assez souvent de l'idiome -- j'ai du code
propre à la classe pour initialiser le tableau, mais par la suite, la
classe apparaît comme une séquence de la norme, avec tout ce que cela
implique : des typedef pour iterator, const_iterator, value_type, etc.,
etc., des fonctions comme begin(), end(), front(), back(), size(), etc.,
etc.

À titre d'exemple, tu pourrais régarder GB_FieldArray ou GB_CommandLine
à ma site.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
Nicolas Aunai
"" a dit :


Et pour qu'il puisse modifier ton vecteur. D'ailleurs, pourquoi des
variables publiques. Je verrais plutôt quelque chose du genre :

class Coup
{
public:
typedef std::vector< std::string >::const_iterator
iterator ;

iterator begin() const
{
return myTab.begin() ;
}
iterator end() const
{
return myTab.end() ;
}
private:
std::vector< std::string >
myTab ;
} ;




oui c'est ce que j'ai fait maintenant.


avec le peu de connaissances que j'ai je dirais que non car objet
constant implique iterator membre constant implique iterator
inutilisable ... ??


Pas du tout. L'important, c'est que l'itérateur n'est pas membre de la
collection. Donc, même si la collection est constante, l'itérateur ne
l'est pas forcement.



ah oui je m'étais peut-etre mal exprimé je voulais dire "si l'iterator
est un membre de la classe", sinon en effet, si c'est une valeur de
retour d'une méthode, l'objet peut-etre constant.


(En revanche, il doit être un const_iterator, c-à-d
grosso modo un itérateur dont l'opérateur * renvoie une référence const,
et non une simple référence, de façon à ce que l'utilisateur ne peut pas
modifier ta collection à travers l'itérateur.)



j'ai compris.


1) dans le codage de mes méthodes ?


Comme partout ailleurs, dans C_Coup, tu obtiens les itérateurs de tab.
Que tu peux rendre publique en les renvoyant d'une fonction, on non,
comme bon te semble.


alors comment accéder a ce nouveau type ?

exemple :

//fichier A.h

class A
{

public :
typedef int entier;
A();
entier methode1();
}

//fichier A.cpp

A()
{
}

entier A::methode1() //erreur de compilation 'syntax error before ::'
{

}



merci pour ton aide !

--
Nico,
http://astrosurf.com/nicoastro
messenger :


Avatar
kanze
Nicolas Aunai ç wrote in message
news:...

[...]
1) dans le codage de mes méthodes ?


Comme partout ailleurs, dans C_Coup, tu obtiens les itérateurs de
tab. Que tu peux rendre publique en les renvoyant d'une fonction,
on non, comme bon te semble.


alors comment accéder a ce nouveau type ?

exemple :

//fichier A.h

class A
{

public :
typedef int entier;
A();
entier methode1();
}

//fichier A.cpp

A()
{
}

entier A::methode1() //erreur de compilation 'syntax error before ::'


A::entier.

En fait, c'est exactement comme n'importe quel autre membre de la classe
qui n'est pas non statique. (Et est-ce que quelqu'un a une meilleur
façon de formuler ces membres -- ce sont les membres qu'on peut utiliser
sans avoir une instance de la classe ?)

À l'intérieur de la classe, le A:: n'est pas nécessaire. En dehors, il
faut bien dire au compilateur où il doit chercher le nom.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16