[C++] Références

Utilité des références par rapport aux pointeurs

Le problème exposé dans ce sujet a été résolu.

Bonjour à toutes et à tous.

J’ai simplement une question à vous poser concernant les références en C++. J’apprends le C++ avec comme support le C++ Primer 5th edition.

Je voulais savoir si j’avais bien saisi l’utilité des références par rapport aux pointeurs :

  • Les références partagent la même adresse que la variable vers laquelle elle référère, un alias en fait quoi. Du coup une référence n’occupe pas de place en mémoire par rapport à un pointeur qui lui a une adresse propre ?
  • Mieux vaut manipuler les références que les pointeurs, car toucher à la mémoire quand on ne sait pas faire on risque de créer des fuites ?
  • Je trouve que passer des arguments par référence aux paramètres d’une fonction est plus intuitif que les pointeurs.

Merci pour vos réponses.

1) Au pire, une référence prend autant de place qu’un pointeur. Mais on s’en fiche en fait, car on ne veut pas savoir comment est implémentée la référence au final.

2) Ben, quand on peut remplacer un pointeur par une référence mieux vaut le faire. Mais dans tous les cas quand on touche à la mémoire on risque de créer des fuites.

3) Je viens du C et du coup, ben je trouve pas que ce soit plus intuitif, tout au contraire même. Car lors de l’appel de fonction, on doit toujours vérifier le prototype pour savoir s’il reçoit son paramètre par valeur ou par référence. Alors qu’en C et en Python, je me pose pas la question, c’est par valeur.

+0 -0

Merci pour ta réponse.

Je viens du C aussi, et j’ai un peu de mal à assimiler toutes les spécifications du C++ Par contre, je trouve que savoir qui prends le moins de place est important, avoir un code optimisé est toujours préférable.

Dans quel cas, pour toi, on ne pourrait pas remplacer un pointeur par une référence par exemple ? Après pour savoir si la variable est passée par référence ou par valeur effectivement il faut vérifier le prototype mais bon si ça permet de ne pas créer de fuites mémoires, et puis si tu travailles sur ton propre code, normalement tu sait ce qu’il va faire à chaque moment précis, non ?

Salut.

Par contre, je trouve que savoir qui prends le moins de place est important, avoir un code optimisé est toujours préférable.

Si le compilateur n’élide pas le pointeur ou la référence, ça revient exactement au même. Mais de toute façon, ce genre de choses est une micro-optimisation qui a peu de chance d’avoir un impact sauf dans des cas très précis (et déterminés via profiling). Ce qui compte c’est l’efficacité et la complexité de tes algorithmes, et l’adéquation de tes structures de données à ton problème.

Pour la question d’origine, si le paramètre est obligatoire, référence, s’il peut être nul, pointeur.

+1 -0

3) […] Alors qu’en C et en Python, je me pose pas la question, c’est par valeur.

ache

Le passage par valeur n’existe pas en python, c’est toujours par référence. Et en C, tu peux te poser la question pour un tableau (en réalité, c’est un pointeur qui est passé, donc une référence).

+1 -0

Pour faire simple, je résonne comme ça :

Objectif Type de référence
On veut faire référence à un objet référence classique
On veut faire référence à un objet, tout en gardant la possibilité de changer l’objet référencé std::reference_wrapper
On veut faire référence à un objet ou à rien, tout en gardant la possibilité de changer l’objet référencé pointeur classique

Le premier cas étant très largement le plus courant.

Mieux vaut manipuler les références que les pointeurs, car toucher à la mémoire quand on ne sait pas faire on risque de créer des fuites ?

p4radox

Tant que la resource n’est pas allouée dynamiquement, il n’y a pas de risque de fuite mémoire. Si une allocation dynamique est nécessaire, on se tournera vers des capsules RAII.

Tant que la resource n’est pas allouée dynamiquement, il n’y a pas de risque de fuite mémoire. Si une allocation dynamique est nécessaire, on se tournera vers des capsules RAII.

Oui, pour les capsules RAII j’ai lu ça tout à l’heure ou il était dit qu’il valait mieux ne pas utiliser ’new’ et ’delete’ au profit de ces dernières, il y a un article dessus ici je crois d’ailleurs.

3) […] Alors qu’en C et en Python, je me pose pas la question, c’est par valeur.

ache

Le passage par valeur n’existe pas en python, c’est toujours par référence. Et en C, tu peux te poser la question pour un tableau (en réalité, c’est un pointeur qui est passé, donc une référence).

yoch

Effectivement ^^"

Pour le C, ce serra toujours par valeur. Il faut juste se souvenir des convertions implicites. Dans le cas des tableaux, tableaux -> pointeur sur le premier élément.

+0 -0

Les problèmes des pointeurs nus sont multiples :

  • Est-ce un élément seul ou le début d’un tableau ?
  • Dois-je le désallouer ? Si oui comment ? free / delete ou delete[] ?

C’est pour ca qu’il faut mieux les éviter autant que faire ce peut et préférer les éléments plus évolués du langage (typiquement make_unique et unique_ptr en cas d’allocation dynamique ou wrapper owner, voir les C++ code guidelines).

Et c’est pour ca que je ne suis pas d’accord avec la dernière ligne du tableau de Olybri: le cas qu’il décrit est clairement couvert par std::optional

+0 -0

Et c’est pour ca que je ne suis pas d’accord avec la dernière ligne du tableau de Olybri: le cas qu’il décrit est clairement couvert par std::optional

Davidbrcz

Je parlais uniquement de références vers un objet déjà existant, non pas vers une resource dont on est propriétaire. Dans le cas du pointeur nu, je pensais à ce genre d’exemple :

1
2
3
4
5
6
7
void messageBox(const std::string & msg, Widget * parent)
{
    if(parent == nullptr)
        // processus sans parent
    else
        // processus avec parent
}

Je ne vois pas comment std::optional pourrait remplacer cette référence.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte