11
votes

Objets C ++: Quand dois-je utiliser le pointeur ou la référence

Je peux utiliser un objet comme point de pointeur, ou sa référence. Je comprends que la différence est que les pointeurs doivent être supprimés manuellement et les références restent jusqu'à ce qu'elles soient hors de portée.

Quand dois-je utiliser chacun d'eux? Quelle est la différence pratique?

Aucune de ces questions n'a répondu à mes doutes:


2 commentaires

Vous n'avez pas à supprimer le pointeur lui-même ainsi que la référence ne supprime pas automatiquement l'objet référencé. Êtes-vous sûr de ne pas dérouter les références et les valeurs de puits / objets?


Je suis à peu près sûr de la différence entre la différence entre valeur / référence. Mon problème est de déclarer un objet comme un pointeur et transmettez le pointeur le long, ou déclarer comme valeur et transmettre sa référence.


9 Réponses :


0
votes

La chose est que vous ne pouvez pas reculer une référence à un autre objet. Les références sont liées à la compilation et ne peuvent pas être nuls ni rebondir. Les pointeurs ne sont donc pas redondants si votre doute était que :)


1 commentaires

Eh bien, votre réponse aide, mais ne résout pas tout. J'ai toujours des doutes quand utiliser la référence à la valeur de l'objet ou utiliser un pointeur pour elle



3
votes

Vous avez de nombreuses situations dans lesquelles un paramètre n'existe pas ou n'est pas valide et cela peut dépendre de la sémantique d'exécution du code. Dans de telles situations, vous pouvez utiliser un pointeur et la définir sur NULL (0) pour signaler cet état. En dehors de cela,

  • Un pointeur peut être ré-attribué à un nouveau Etat. Une référence ne peut pas. C'est souhaitable dans certaines situations.
  • Un pointeur aide à transférer la sémantique du propriétaire-navire. Ceci est particulièrement utile dans l'environnement multi-threadé si l'état de paramètre est utilisé pour exécuter dans Un fil séparé et vous ne sondez généralement pas que le fil ait disparu. Maintenant, le fil peut le supprimer.

0 commentaires

18
votes

Une référence est essentiellement un pointeur avec des restrictions (doit être lié à la création, ne peut pas être rebondir / null). S'il est logique que votre code utilise ces restrictions, vous utilisez une référence au lieu d'un pointeur permet au compilateur de vous avertir de vous les violer accidentellement.

C'est beaucoup comme le qualificatif Const Const: la langue pourrait exister sans elle, il est juste là en tant que caractéristique de bonus de sorte que cela facilite la mise au point de code sécurisé.


3 commentaires

Vous voulez dire si j'ai un pointeur constant, il se comporte à peu près comme une référence?


Non, la comparaison Const ne serait pas conçue pour être pertinente pour les pointeurs en soi: les pointeurs de const et les références ne sont pas les mêmes (plus à ce sujet ici: Parasht.com/c ++ - FAQ-Lite / références.html # FAQ-8.5 ). Ce n'était qu'un exemple d'une caractéristique linguistique qui applique certaines sémantiques afin que vous n'ayez pas à faire.


"La langue pourrait exister sans elle" - C ++ pourrait exister sans références, mais il y aurait alors des choses que vous ne pouviez plus faire, que vous pouvez faire aujourd'hui (donc ce ne serait donc pas le même langue). Par exemple, certaines constructions de surcharge de l'opérateur ne peuvent être effectuées qu'avec des références, pas des pointeurs. Exemple: si vous souhaitez utiliser l'opérateur enchaînant avec l'opérateur d'affectation.



2
votes

erm ... pas exactement. C'est l'identifiant qui a une portée. Lorsque vous créez un objet en utilisant Nouveau code>, mais la portée de son identifiant se termine, vous pouvez vous retrouver avec une fuite de mémoire (ou non - dépend de ce que vous voulez réaliser) - L'objet est dans la mémoire, mais Vous n'avez plus de moyens de le référencer plus.

La différence est qu'un pointeur est une adresse en mémoire, donc si vous avez, disons, ce code: p> xxx pré>

A code> est un pointeur. Vous pouvez l'imprimer - et vous obtiendrez quelque chose comme "0x0023f1" - c'est juste que: une adresse. Il n'a aucune valeur (bien que certaines valeurs soient stockées dans la mémoire à cette adresse). P>

#include <iostream>

using namespace std;

int main()
{
    int * a = new int;
    int b = 10;
    cout << "address of a: " << a << endl;
    cout << "address of b: " << &b << endl;
    cout << "value of a: " << *a << endl;
    cout << "value of b: " << b << endl;
    a = &b; //comment/uncomment
    //*a = b; //comment/uncomment
    cout << "address of a: " << a << endl;
    cout << "address of b: " << &b << endl;
    cout << "value of a: " << *a << endl;
    cout << "value of b: " << b << endl;
}


0 commentaires

2
votes

Répondons d'abord à la dernière question. Alors la première question aura plus de sens.

Q: "Quelle est la différence pratique [entre un pointeur et une référence]?"

a: une référence est juste un pseudonyme local pour une autre variable. Si vous passez un paramètre par référence, ce paramètre est exactement la même variable que celle indiquée dans l'instruction appelante. Cependant, en interne, il n'y a généralement aucune différence entre un pointeur et une référence. Les références fournissent "Syntaxe Sugar" en vous permettant de réduire la quantité de taper que vous devez faire lorsque tout ce que vous vouliez vraiment avoir été accédé à une seule instance d'une variable donnée.

Q: "Quand devrais-je utiliser chacun des em?"

A: Cela va être une question de préférence personnelle. Voici la règle de base que je suive. Si je vais avoir besoin de manipuler une variable dans une autre portée et que cette variable est soit un type intrinsèque, une classe qui doit être utilisée comme un type intrinsèque (c.-à-d. STD :: String, etc.), ou une const instance de classe, puis je passe par référence. Sinon, je passerai par le pointeur.


0 commentaires

3
votes

Suszterpatt a déjà donné une bonne explication. Si vous voulez une règle de base facile à retenir, je suggérerais ce qui suit:

Si possible, utilisez des références, utilisez uniquement des pointeurs si vous ne pouvez pas les éviter.

Même plus court: préférez références sur les pointeurs.


0 commentaires

4
votes

Voici une autre réponse (peut-être que j'aurais dû éditer le premier, mais comme cela a un objectif différent, je pensais qu'il serait correct de les avoir séparé).

Lorsque vous créez un pointeur avec neuf CODE>, la mémoire pour elle est réservée et elle persiste jusqu'à ce que vous appelle Supprimer code> dessus - mais la durée de vie de l'identifiant est toujours limitée à la fin du bloc de code. Si vous créez des objets dans une fonction et que vous les appendez à une liste externe, les objets peuvent rester en toute sécurité dans la mémoire après la retouche de la fonction et vous pouvez toujours les référencer sans l'identifiant. P>

Voici un exemple (simplifié) De l'Ombra, un cadre C ++ que je développe. Il y a une liste de modules (pointeurs vers des objets) stockés dans le moteur. Le moteur peut ajouter un objet à cette liste: P>

void getVal (int * a) {
    *a = 10;
}
int main() {
    int b;
    getVal(&b);
    return b;
}


0 commentaires

8
votes

"Pointeurs que je dois supprimer et référencer qu'ils restent jusqu'à la fin de leur champ d'application."

Non, c'est complètement faux.

Objets qui sont attribués avec Nouveau doivent être supprimés [*]. Les objets qui ne sont pas attribués avec neuf ne doivent pas être supprimés. Il est possible d'avoir un pointeur sur un objet qui n'a pas été attribué avec nouveau , et il est possible d'avoir une référence à un objet attribué avec nouveau .

Un pointeur ou une référence est un moyen d'accéder à un objet, mais n'est pas l'objet lui-même et n'a aucune incidence sur la manière dont l'objet a été créé. La différence conceptuelle est qu'une référence est un nom pour un objet et un pointeur est un objet contenant l'adresse d'un autre objet. Les différences pratiques, comment vous choisissez lequel à utiliser, incluez la syntaxe de chacun et le fait que les références ne peuvent pas être nuls et ne peuvent pas être réinstallées.

[*] avec Supprimer . Un tableau attribué avec Nouveau [] doit être supprimé avec Suppr [] . Il existe des outils disponibles qui peuvent aider à garder une trace des ressources allouées et à vous procurer ces appels, appelées pointeurs intelligents. Il devrait donc être assez rare d'appeler explicitement l'appel vous-même, par opposition à simplement arranger pour qu'il soit fait, mais néanmoins il doit être fait.


0 commentaires

0
votes

Comme mon enseignant C ++ l'utilisait, les pointeurs pointent sur l'emplacement de la mémoire pendant que des références sont alias . Par conséquent, le principal avantage est qu'ils peuvent être utilisés de la même manière que le nom de l'objet qu'ils font référence, mais dans une portée où l'objet n'est pas disponible en le transmettant là-bas.

tandis que les pointeurs peuvent être redirigés vers un autre emplacement, des références étant comme des pointeurs constants, ne peuvent pas être redirigées. Les références ne peuvent donc pas être utilisées pour traverser des tableaux dans une fonction, etc.

Cependant, un pointeur étant une entité distincte prend une certaine mémoire, mais la référence étant identique à celle de l'objet référé ne prend aucun espace supplémentaire. C'est l'un de ses avantages.

J'ai également lu que le temps de traitement des références est inférieur,

comme

int & i = b;

i ++; prend moins de temps que

int * j = b;

(* j) ++;

Mais je dois encore confirmer cela. Si quelqu'un peut jeter la lumière sur cette revendication, ce serait génial.

Les commentaires sont les bienvenus :)


0 commentaires