Salut, et bienvenue sur le forum
Envoyé par
Obsidian
Bonjour,
Une référence n'est pas un objet en elle-même. Son nom suffit à décrire ce dont il s'agit : on se réfère à un objet existant. Le tout se passe au niveau de la compilation.
ca, c'est juste...
Envoyé par
Obsidian
Si tu crées une variable locale x et que tu fais une référence y, tu as en fait créé un alias de son symbole.
ca aussi, à condition de préciser "et que tu l'associe au symbole concerné
Envoyé par
Obsidian
Si, en revanche, la référence est spécifiée dans les paramètres, le compilateur devra se débrouiller pour faire référence à un objet qui n'existe pas encore et pour cela, il passera probablement un pointeur qui sera masqué au programmeur.
Ca, par contre, c'est faux...
Deux solutions sont à envisager:
soit le paramètre transmis est une variable existante, soit tu fournis une information compatible avec la création d'une variable anonyme.
Ainsi, avec la fonction
1 2 3 4
| void foo(const std::string& r)
{
/* n'importe quoi */
} |
tu peux écrire un code proche de
1 2 3
| std::string s;
/* préciser le texte contenu par s, de n'importe quelle manière */
foo(s); |
et, dans foo, p reste tout à fait l'alias de la chaine s de la fonction appelante.
Par contre, comme il existe un constructeur de std::string qui prend, en paramètre un const char*, il est aussi possible de l'appeler sous la forme de
foo("le texte a utiliser");
A ce moment là, parce que la référence est déclarée constante, la norme accepte qu'il y ait création d'une variable anonyme (car tu ne peut pas y accéder en dehors de foo) dont la durée de vie sera exactement... la durée d'exécution de la fonction appelée, qui sera utilisée lors de la création de la référence r, qui sera utilisée au sein de la foo de manière tout à fait normale.
Envoyé par
Obsidian
Cela veut dire que la libération éventuelle d'une ressource est indépendante de la référence proprement dite, puisque tu peux te référer aussi bien à un objet dans la pile à qu'à un objet créé en amont avec new().
Attention, un pointeur n'est pas *forcément* synonyme d'allocation dynamique de la mémoire (et de tout ce qui va avec)...
Bien sur, le terme pointeur est souvent associé au concept de gestion dynamique de la mémoire, mais, s'arrêter à cette association est par trop restrictif
Un pointeur n'est jamais qu'une variable dont la valeur représente l'adresse à laquelle nous trouverons effectivement une instance du type concerné
La preuve, le code suivant est tout à fait valide
1 2 3 4 5 6 7 8 9 10 11
| /* MaClasse est une classe existante ;) */
MaClasse cl;
MaClasse* ptr = &cl;
/* voire */
void foo(MaClasse* p)
{
/*....*/
}
/*appelée sous la forme de */
MaClasse obj;
foo(&obj); |
Dés lors, il faut savoir que
- l'alias (la référence) est disponible tant que l'on est dans la portée dans laquelle se trouve sa déclaration
- La variable est détruite lorsque l'on quitte la portée dans laquelle elle est déclarée
- Si nous travaillons avec une allocation dynamique de la mémoire (new ou new[]), nous acceptons d'être nous-même responsable de la libération de cette mémoire (delete ou delete[]) au plus tard avant de perdre la variable qui nous permet d'y accéder (et en veillant à ne pas tenter une double libération, s'il échoit)
Envoyé par
Obsidian
C'est donc toujours à toi de vérifier au cas par cas la bonne libération des ressources que tu alloues.
Ca, c'est vrai, et c'est faux:
C'est vrai si tu précise que tu alloues ces ressource dynamiquement, c'est faux si tu ne précise rien, car, stricto sensu, tu alloue une ressource en écrivant un code aussi simple que
(tu réserve un espace mémoire suffisant pour y placer la valeur d'un entier de type int, et tu alloue cet espace à la variable i )
Partager