IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

Conteneurs STL et références


Sujet :

SL & STL C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 38
    Points : 34
    Points
    34
    Par défaut Conteneurs STL et références
    Apparemment, il n'est pas possible de créer un conteneur de références.

    Sous visual, ce code ne compile pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Foo
    {
    };
     
    int main()
    {
    	std::vector<Foo&> fooVector;
    	return 0;
    }
    J'ai l'erreur : error C2528: 'pointer' : pointer to reference is illegal

    Si on part du fait qu'une référence est un alias d'objet, je ne comprends pas pourquoi ca pose problème ?

    Est ce que quelqu'un à l'explication ?

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Parce que ça n'a pas de sens.
    Un conteneur stocke des objets, des valeurs.

    À noter que la version actuelle des conteneurs nécessite que le type contenu soit CopyConstructible et Assignable.
    Boost ftw

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2006
    Messages : 30
    Points : 42
    Points
    42
    Par défaut
    Salut,

    Google est ton ami :

    Visual C++ Concepts: Building a C/C++ Program
    Compiler Error C2528

    Error Message
    'name' : pointer to reference is illegal

    You cannot declare a pointer to a reference. Dereference the variable before declaring a pointer to it.
    En clair tu ne peux pas déclarer un pointeur de référence. Moi je ferais de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Foo
    {
    };
     
    int main()
    {
    	std::vector<Foo *> fooVector;
    	return 0;
    }
    Tu as donc un un tableau redimensionnable dont chaque case pointe vers un objet de type Foo. Pour ajouter, tu push_back l'adresse de ton objet de type Foo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int main()
    {
    	std::vector<Foo *> fooVector;
            Foo objetFoo;
     
            fooVector.push_back(&objetFoo);
     
    	return 0;
    }

  4. #4
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 38
    Points : 34
    Points
    34
    Par défaut
    @loufoque : ok, mais une référence en mémoire est bien représentée par une valeur ?

    On écrit bien vector<Foo*> qui stocke des pointeurs, donc une valeur sur 32/64 bits. Pourquoi pas une référence ? Je suppose qu'il y a une correspondance dans la mémoire ?


    @mikado : pas besoin de google, Visual me dis ca tout seul !
    Et effectivement passer par des pointeurs est la solution "classique", que j'ai toujours fait jusqu'à présent. Mais je voudrais connaitre la RAISON. La solution est bien sur, comme tu l'as mis vector<Foo*> ou carrement vector<Foo>.

  5. #5
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Points : 833
    Points
    833
    Par défaut
    écrire vector<Foo*> est dangeureux. Utilises plutôt des smart pointers dans ce cas ou une structure adaptée pour passer d'un élément à l'autre (sans vector)
    Linux > *

  6. #6
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Points : 833
    Points
    833
    Par défaut
    et pour répondre à la question initiale: tu oublies qu'une référence doit être obligatoirement initialisé et ne peut être NULL.
    Linux > *

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2006
    Messages : 30
    Points : 42
    Points
    42
    Par défaut
    @mikado : pas besoin de google, Visual me dis ca tout seul !
    Je n'utilise pas Visual Studio, je préfère travailler sous UNIX directement avec des makefiles ^^ . Merci pour l'info.

    La référence permet de faire référence à des objets qui existent déjà.

    Le concept de référence ne doit en aucun cas être confondu avec celui d'adresse même si les deux notions utilisent le caractère &.
    Faire un conteneur de référence ne me parait pas logique dans le sens où justement ce n'est pas vraiment une adresse mais un "pointeur sur un objet précis". Or on ne va pas faire un conteneur sur un objet précis. (Ce n'est que mon avis, je ne me suis jamais posé cette question :p)

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par rockeye Voir le message
    @loufoque : ok, mais une référence en mémoire est bien représentée par une valeur ?

    On écrit bien vector<Foo*> qui stocke des pointeurs, donc une valeur sur 32/64 bits. Pourquoi pas une référence ? Je suppose qu'il y a une correspondance dans la mémoire ?
    Il faut bien te rendre compte qu'une référence n'a pas d'existance en tant que telle...

    Ce n'est jamais qu'un alias d'un objet existant.

    Comme une référence va, en très gros, dire "salut, je mappelle (le nom) et je représente (la variable d'origine)", on ne peut pas prendre le risque que la variable d'origine... n'existe pas

    Et, comme une référence n'a pas d'existance en soi, il est donc impossible... d'en prendre l'adresse

    D'ailleurs, si tu voulais t'amuser à une petit exercice de "bon parler", je te proposerais bien de me donner la signification des expressions suivantes:
    1. int i =3;
    2. int & ref =i;
    3. int * ptr = &i;
    4. int &* pr = &ref;
    5. int *& rp = ptr;
    (en sachant que toutes ne sont pas forcément juste)...

    Et tu te rendrais rapidement compte, en remplaçant le terme "référence sur" par "alias de" de quels expressions sont mauvaises
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 38
    Points : 34
    Points
    34
    Par défaut
    OK, je commence à comprendre le concept.

    Merci à tous pour vos réponses.

  10. #10
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Juste pour enfoncer le clou: une erreur que l'on retrouve beaucoup dans les discussions en c++ est de dire qu'un pointeur et une référence c'est la même chose. C'est bien évidemment faux, un pointeur est un objet qui contient une adresse (ce qui permet de définir des opérations sur les pointeurs, cf l'arithmétique de pointeurs), alors qu'une référence est la valeur de l'adresse elle-même.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  11. #11
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 38
    Points : 34
    Points
    34
    Par défaut
    On est d'accord, c'est comme cela que je l'avais compris.

    Si j'ai bien compris, le problème n'est pas "hardware" :

    On pourrait dans l'absolu stocker une référence dans un vect (c'est la valeur d'une adresse, donc un nombre, et un nombre c'est un int ou long, donc stockable dans un vector),

    MAIS, le verrou est "logiciel" (enfin, venant du compilo) parce qu'une référence ne peut pas être nulle, notamment. Et en stockant la valeur de l'adresse d'un objet, on prend le risque que cet objet disparaisse, et que la référence stockée pointe sur quelque chose d'invalide, ce qui contredit le concept de référence.

    J'ai tout juste ?

  12. #12
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par rockeye Voir le message
    On est d'accord, c'est comme cela que je l'avais compris.

    Si j'ai bien compris, le problème n'est pas "hardware" :

    On pourrait dans l'absolu stocker une référence dans un vect (c'est la valeur d'une adresse, donc un nombre, et un nombre c'est un int ou long, donc stockable dans un vector),
    Effectivement. D'ailleurs on peut le faire. Tu stocke des int dans ton conteneur, et tu les utilise comme des pointeurs. Mais bon, voilà le cahos!

    Citation Envoyé par rockeye Voir le message
    MAIS, le verrou est "logiciel" (enfin, venant du compilo) parce qu'une référence ne peut pas être nulle, notamment. Et en stockant la valeur de l'adresse d'un objet, on prend le risque que cet objet disparaisse, et que la référence stockée pointe sur quelque chose d'invalide, ce qui contredit le concept de référence.

    J'ai tout juste ?
    Oui je crois. Enfin... je ne suis pas sûr de bien tout comprendre. On peut stocker des pointeurs dans un conteneurs et ces pointeurs peuvent pointer sur quelque chose d'invalide aussi. C'est la raison pour laquelle il est déconseillé de faire des conteneurs de pointeurs (bien qu'en réalité, ça peut être le meilleur choix dans certains cas bien précis - et assez rares en fait je crois.).
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème avec les conteneurs STL
    Par burak dans le forum SL & STL
    Réponses: 7
    Dernier message: 19/04/2009, 17h43
  2. Passage d'un conteneur stl a un pthread
    Par bossbebes dans le forum SL & STL
    Réponses: 4
    Dernier message: 04/04/2009, 15h20
  3. Conteneurs STL : passage d'arguments par référence
    Par bolhrak dans le forum SL & STL
    Réponses: 0
    Dernier message: 26/09/2007, 20h54
  4. type conteneur stl
    Par star_light dans le forum SL & STL
    Réponses: 5
    Dernier message: 15/02/2005, 23h51
  5. Fonction polymorphe et conteneur stl.
    Par Captain Fizzou dans le forum SL & STL
    Réponses: 2
    Dernier message: 29/11/2004, 19h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo