OVH Cloud OVH Cloud

STL - for_each et Objet fonction

58 réponses
Avatar
fred
Bonjour,

l'id=E9e est assez simple. Comment puis je r=E9cup=E9rer une
variable/instance de type vector apr=E8s l'appel l'algorithm for_each.
Comme dans l'exemple. Je parcours une string. pour chaque car.
convertit en entier que je place dans un vector<int>.
Mais apr=E8s l'appel =E0 for_each comme puis je acc=E9der au vector ?

merci d'avance

Fr=E9d=E9ric

class ConvertCharToInt
{
vector<int> vFmt;
public:
void operator() (char c)
{
vFmt.push_back(atoi(c));
}
};

class CFmt
{
public :
string szFmt;
void GetStringFormat(const string a){ szFmt=3D a;};
void SplitFmt(){
std::for_each(szFmt.begin(),szFmt.end(),ConvertCharToInt());
};
};
main()
{
CFmt *obj;
obj=3D new CFmt;
obj->GetStringFormat("123456");
obj->SplitFmt();
delete obj;
}

10 réponses

2 3 4 5 6
Avatar
Gabriel Dos Reis
"kanze" writes:

| Fabien LE LEZ wrote:
| > On Wed, 22 Feb 2006 14:47:59 +0100, "Michel Decima" :
|
| > >C'est juste. Mais d'un autre coté, il n'y a pas de classe, vu
| > >que "class" introduit une structure dont les membres et
| > >l'héritage sont privés par défaut.
|
| > Pas vraiment. La notion de "structure" semble assez floue :
| > apparemment elle est utilisée dans la norme, mais ça ressemble
| > plus à un oubli qu'à une volonté de piquer ce mot au langage
| > C. La notion de classe, en revanche, est une notion
| > fondamentale en C++ et dans les autres langages OO.
|
| Dans la norme, « structure » et « union » sont des types de
| classes -- toutes les structures et toutes les unions sont des
| classes, mais l'inverse n'est pas vrai.
|
| Dans le cas d'union, la distinction a un sens ; une union se
| distingue des autres classes d'une manière significative. Dans
| le cas de structure, c'est plus discutable. N'empèche qu'on a
| (§9/4) : "A structure is a class defined with the class-key
| struct;" et "A union is a class defined with the class-key
| union".
|
| Note bien le mot « defined » dans les deux cas. Si j'écris :
|
| class Toto ;
| struct Titi ;
| union Tata ;
|
| je n'ai rien défini, et pour l'instant, on a trois classes, dont
| on ne sait pas si elles sont des structures ou des unions. On
| peut très bien faire par la suite :
|
| union Toto { } ;
| class Titi { } ;
| struct Tata { } ;

jk.C:5: error: 'union' tag used in naming 'struct Toto'
jk.C:7: error: 'struct' tag used in naming 'union Tata'

-- Gaby
Avatar
Jean-Marc Desperrier
fred wrote:
La solution pouvait être aussi :


class ConvertCharToInt
{
vector<int> vFmt;
[...]
vector<int>& getVector() { return vFmt; }
};

[...]

vector<int> vRec;
vRec= Vect.getVector();


J'ai un paire de question vraiment basique par rapport à cet idiome,
mais pas encore trouvé un point clair sur ces questions.

Ici, vRec sera finalement initialisé par copie ?

Si on faisait ceci, on éviterait la copie ?
vector<int> &vRec = Vect.getVector();

Et ici par contre, on ne pourra pas éviter d'avoir deux copies successives ?
vector<int> getVector() { return vFmt; }

vector<int> vRec = Vect.getVector();

Finalement, renvoyer par référence les données d'un getter de ce genre
est-ce un bonne idée ou non ? Parceque si cela permet d'éviter des
duplications inutiles, cela rend le getter beaucoup plus susceptible
d'avoir des effets de bords quand il est mal utilisé.

Avatar
fred
Merci james.

Oui je regard cet alg. transform... Pas simple non plus à mettre en
place.
Avatar
Franck Branjonneau
Jean-Marc Desperrier écrivait:

fred wrote:
La solution pouvait être aussi :
class ConvertCharToInt
{ vector<int> vFmt;
[...]
vector<int>& getVector() { return vFmt; }
};

[...]

vector<int> vRec;
vRec= Vect.getVector();


J'ai un paire de question vraiment basique par rapport à cet idiome,
mais pas encore trouvé un point clair sur ces questions.

Ici, vRec sera finalement initialisé par copie ?


Non, par défaut. Une assignation suivra.

Il aurait fallu écrire :

vector<int> vRec(Vect.getVector());

ou

vector<int> vRec= Vect.getVector();

pour une copie.


Si on faisait ceci, on éviterait la copie ?
vector<int> &vRec = Vect.getVector();


Oui.


Et ici par contre, on ne pourra pas éviter d'avoir deux copies successives ?
vector<int> getVector() { return vFmt; }

vector<int> vRec = Vect.getVector();


Le compilateur est autorisé a faire l'élision : une ou deux copies.


Finalement, renvoyer par référence les données d'un getter de ce genre
est-ce un bonne idée ou non ?


Oui. Mais Gabriel Dos Reis, je crois, s'interrogeait sur son utilité :
pourquoi ne pas faire de vFmt un membre public ?


Parceque si cela permet d'éviter des duplications inutiles, cela
rend le getter beaucoup plus susceptible d'avoir des effets de bords
quand il est mal utilisé.


Je n'ai pas compris ce que tu voulais dire.

--
Franck Branjonneau


Avatar
James Kanze
Gabriel Dos Reis wrote:
"kanze" writes:


wrote:



La différence entre une classe et une structure est l'endroit où
elles sont stockées ? je me trompe ?




Oui.



Pour commencer, le C++ a des types de classe. Il n'y a pas de
type « structure », ni, en fait, « union ». Dans les
déclarations, les trois mots clé ont strictement la même
signification.



union U;
// ...
struct U { };
int main()
{
U u;
}


jk.C:3: error: 'struct' tag used in naming 'union U'


J'ai connu un compilateur qui faisait ça avec struct et class aussi:-).

Mais en effet, il y a une restriction supplémentaire cachée dans une
autre section que je n'ai pas vue.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34



Avatar
Franck Branjonneau
Jean-Marc Desperrier écrivait:

Je faisait finalement surtout référence au fait qu'il manque ici un
"const" pour assurer que le getter par référence "vector<int>&
getVector() { return vFmt; }" ne soit utisable qu'en lecture.


Un seul ?

vector<int> const & getVector() { return vFmt; }

ou

vector<int> & getVector() const { return vFmt; }

à moins que

vector<int> const & getVector() const { return vFmt; }

;)


On peut souhaiter réellement utiliser le getter pour obtenir un
exemplaire où les modifications se repportent directement dans l'objet
source, mais ce cas d'utilisation est alors très différent du getter
par copie.


Il n'y a pas de « getter par copie ».

Pour une fonction get const soit tu retournes une valeur (l'objet est
petit) soit tu retournes une const référence (l'objet est gros) et
l'appelant se débrouille.

Une fonction get non const ne devrait retourner qu'une référence.

Au point je pense qu'il vaudrait mieux qu'il n'ait pas le même nom.


C'est un point de vue. Est-ce qu'il tient pour les getters que sont
les operator[], les fonctions at(), ... ?

--
Franck Branjonneau

Avatar
kanze
Jean-Marc Desperrier wrote:
fred wrote:
La solution pouvait être aussi :

class ConvertCharToInt
{
vector<int> vFmt;
[...]
vector<int>& getVector() { return vFmt; }
};


[...]
vector<int> vRec;
vRec= Vect.getVector();


J'ai un paire de question vraiment basique par rapport à cet
idiome, mais pas encore trouvé un point clair sur ces
questions.

Ici, vRec sera finalement initialisé par copie ?


Franck en a déjà répondu : c'est une affectation que tu fais, et
non une initialisation. Et il y aura bien une copie, parce qu'il
faut bien qu'il y a deux objets par la suite : le
ConvertCharToInt::vFmt et vRec sont deux objets distincts,
chacun avec da propre durée de vie, et chacun qui pourrait
évoluer d'une façon indépendante de l'autre.

Si on faisait ceci, on éviterait la copie ?
vector<int> &vRec = Vect.getVector();


Ici, tu n'a qu'un seul objet. Ce qui ne va pas forcément sans
faire de problèmes. Considère, par exemple, un cas comme :

ConvertCharToInt* pCvt ;
// ...
vector< int >& vRec = pCvt->getVector() ;
delete pCvt ;
// Et qu'est-ce qu'on fait avec vRed maintenant ?

La sémantique en est bien différente. Il faut choisir entre les
deux en fonction de la sémantique voulue.

En fait, évidemment, si tu as une fonction qui renvoie une
référence à non-const, comme ici, autant rendre le membre
public. Typiquement, un getter renvoie soit une copie de
l'objet, soit une référence const. De façon à ce que
l'encapsulation ne soit pas violée.

Et ici par contre, on ne pourra pas éviter d'avoir deux copies
successives ?

vector<int> getVector() { return vFmt; }
vector<int> vRec = Vect.getVector();


Ici, parce qu'il s'agit d'une initialisation, une copie suffit.
La machine abstraite en fait deux, mais la norme en autorise
explicitement la suppression d'une, même dans le cas où le
constructeur de copie a des effets de bord.

Finalement, renvoyer par référence les données d'un getter de
ce genre est-ce un bonne idée ou non ?


D'habitude, on renvoie par référence const si l'objet est
complexe ; c'est particulièrement intéressant dans le cas où
l'utilisateur n'ait pas besoin d'un deuxième objet indépendant,
par exemple :

int i = vect.getVector()[ 4 ] ;

Parceque si cela permet d'éviter des duplications inutiles,
cela rend le getter beaucoup plus susceptible d'avoir des
effets de bords quand il est mal utilisé.


Un getter ne permet pas d'habitude une modification de l'objet.
Il renverra donc soit une copie, soit une référence à const. (De
même, il serait const lui-même.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Franck Branjonneau
"kanze" écrivait:

Un getter ne permet pas d'habitude une modification de l'objet.
Il renverra donc soit une copie, soit une référence à const. (De
même, il serait const lui-même.)


L'anglais est une langue pauvre ;-) En français tu as accesseur en
lecture (seule) ; accesseur en écriture (seule) et accesseur en
lecture/écriture. Comment tu appelles le dernier en anglais ?

--
Franck Branjonneau

Avatar
Gabriel Dos Reis
Franck Branjonneau writes:

| "kanze" écrivait:
|
| > Un getter ne permet pas d'habitude une modification de l'objet.
| > Il renverra donc soit une copie, soit une référence à const. (De
| > même, il serait const lui-même.)
|
| L'anglais est une langue pauvre ;-) En français tu as accesseur en
| lecture (seule) ; accesseur en écriture (seule) et accesseur en
| lecture/écriture. Comment tu appelles le dernier en anglais ?

read
write
readwrite
?

-- Gaby
Avatar
Franck Branjonneau
Gabriel Dos Reis écrivait:

Franck Branjonneau writes:

| "kanze" écrivait:
|
| > Un getter ne permet pas d'habitude une modification de l'objet.
| > Il renverra donc soit une copie, soit une référence à const. (De
| > même, il serait const lui-même.)
|
| L'anglais est une langue pauvre ;-) En français tu as accesseur en
| lecture (seule) ; accesseur en écriture (seule) et accesseur en
| lecture/écriture. Comment tu appelles le dernier en anglais ?

read
write
readwrite
?


Non, nous parlions de getter/setter. James dit qu'un getter est
const.

class S {

int i_;

public:
int & i() { return i_; }
};

Qu'est-ce que i ? Pas un getter, un setter (non, il prendrait un
argument) ? Ou bien ?

--
Franck Branjonneau

2 3 4 5 6