OVH Cloud OVH Cloud

accès à un élément d'un vector n'existant pas obligatoirement

4 réponses
Avatar
Zlika
Bonjour à tous,
Mon pb est le suivant:
Une de mes classes contient un vector d'objets (vector<Objet> objs;).
Ces objets contiennent un identifiant (Id).
Je voudrais avoir des fonctions d'accès permettant de récupérer l'objet
contenant le "Id" demandé.
Mon problème est que je ne connais pas a priori ces Id (c'est-à-dire que si
je sais que j'ai un vector de 10 objets, les Id ne vont pas forcémment de 1
à 10 par exemple, il peut y avoir des trous dans la numérotation). Aussi il
est légitime de demander un Id qui n'existe peut etre pas.

La première fonction crée est simple: elle me revoie une copie de l'objet
demandé, ou un objet vide (Id=-1) si elle ne le trouve pas:
Objet Get_Objet_par_Id(int Id) const {if (objet trouvé) return objet; else
{Objet objet_vide; return objet_vide;};

Je souhaiterais également avoir une version "non-const" de la fonction afin
de pouvoir modifier l'objet trouvé.
Le problème est que je ne peux pas renvoyer une référence (objet_vide est
une variable locale. Ou alors je crée une variable globlale objet_vide que
je renvoie, mais dans ce cas, la fonction appellante pourrait très bien le
modifier.).
Et si je renvoie un pointeur (ou NULL si pas trouvé), les 2 versions "const"
et "non-const" de la fonction sont très asymétriques, ce qui n'est pas très
élégant ni pratique.

J'imagine que c'est un cas d'école et qu'il doit exister une solution
élégante à ce problème.
Merci pour vos réponses!

4 réponses

Avatar
James Kanze
Zlika wrote:

Mon pb est le suivant:
Une de mes classes contient un vector d'objets (vector<Objet> objs;).
Ces objets contiennent un identifiant (Id).
Je voudrais avoir des fonctions d'accès permettant de récupérer l'o bjet
contenant le "Id" demandé.
Mon problème est que je ne connais pas a priori ces Id (c'est-à-dire que si
je sais que j'ai un vector de 10 objets, les Id ne vont pas forcémment de 1
à 10 par exemple, il peut y avoir des trous dans la numérotation). Au ssi il
est légitime de demander un Id qui n'existe peut etre pas.

La première fonction crée est simple: elle me revoie une copie de l'o bjet
demandé, ou un objet vide (Id=-1) si elle ne le trouve pas:
Objet Get_Objet_par_Id(int Id) const {if (objet trouvé) return objet; e lse
{Objet objet_vide; return objet_vide;};

Je souhaiterais également avoir une version "non-const" de la fonction afin
de pouvoir modifier l'objet trouvé.
Le problème est que je ne peux pas renvoyer une référence (objet_vi de est
une variable locale. Ou alors je crée une variable globlale objet_vide que
je renvoie, mais dans ce cas, la fonction appellante pourrait très bien le
modifier.).
Et si je renvoie un pointeur (ou NULL si pas trouvé), les 2 versions "c onst"
et "non-const" de la fonction sont très asymétriques, ce qui n'est pa s très
élégant ni pratique.

J'imagine que c'est un cas d'école et qu'il doit exister une solution
élégante à ce problème.


Qu'est-ce qui ne va pas avec std::find_if. Qui ne renvoie pas un
objet par valeur, mais un itérateur qui désigne l'objet, ou
l'itérateur de fin s'il n'existe pas ?

Sinon, une solution classique est de renvoyer un pointeur, avec
un pointeur null si on n'a pas trouvé l'objet. Sinon, une autre
solution classique, c'est Fallible, mais je ne crois pas qu'il
convient ici, où tu veux en fait l'objet même, et non une copie
de l'objet.

--
James Kanze (Gabi Software) email:
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
Zlika
Merci pour la réponse, mais si je renvoie un itérateur, la fonction ne peut
plus être "const".
Donc j'ai le meme problème que si je renvoie un pointeur: les fonctions
"const" et "non-const" sont très différentes.
Avatar
Falk Tannhäuser
Zlika schrieb:
Merci pour la réponse, mais si je renvoie un itérateur, la fonction ne peut
plus être "const".


Et si tu renvoies un const_iterator ?

Falk

Avatar
James Kanze
Zlika wrote:
Merci pour la réponse, mais si je renvoie un itérateur, la fonction n e peut
plus être "const".


Si tu renvoie un itérateur non-const, la fonction ne peut pas
être const, parce que tu permets à l'utilisateur d'en modifier
les données. Je croyais que c'était ce que tu voulais ; que ton
problème était justement de définir une version non-const de la
fonction, qui permettait à l'utilisateur de modifier les
données.

Donc j'ai le meme problème que si je renvoie un pointeur: les fonctions
"const" et "non-const" sont très différentes.


Tout à fait. Il est assez habituel dans de tels cas de fournir
deux fonctions quasiment identiques, une const, qui renvoie un
const_iterator ou un pointeur à const, et une deuxième non-const
qui renvoie iterator ou T*, ce qui permet la modification de
l'objet.

--
James Kanze (Gabi Software) email:
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