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

 C++ Discussion :

retour par référence et new


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2
    Par défaut retour par référence et new
    Bonjour,
    Étant novice dans l'utilisation du retour par référence je me demande ce qui suit:
    j'ai une classe (Point3D qui comporte les variables x,y et z ) dont une méthode (ci-bas) effectue un retour par référence d'un Vecteur3D (autre classe). Ma question, dois-je utiliser "delete" comme je le fais actuellement? Merci.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // calcules le vecteur entre le point actuel et le point P
    Vecteur3D & Point3D::operator - ( Point3D P )
    {
       Vecteur3D * Q = new Vecteur3D();
     
        (*Q).x = x - P.x;
        (*Q).y = y - P.y;
        (*Q).z = z - P.z;
        return *Q;
        delete Q;
    }

  2. #2
    Membre chevronné
    Avatar de myzu69
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 220
    Par défaut
    Salut,

    je ne comprends pas bien ce que tu veux faire là mais il y a visiblement des problèmes ...

    Pourquoi retourner un Vecteur3D quand tu soustrait deux Point3D ? Je vois bien qu'un vecteur est calculé en soustrayant les coordonnées des deux points extrémités mais j'ai du mal à voir les différences, le code des deux classes est-il différent pour devoir séparer les deux ?

    En admettant que la classe Vecteur3D soit nécessaire, pourquoi ne pas avoir créé un constructeur qui prend en paramètres les valeurs en x, y et z ?

    Enfin pour répondre à ta question, je ne comprends pas pourquoi tu crée un Vecteur3D dynamique, avec ton code, le delete ne sera jamais atteint et l'objet ne sera pas supprimé. Pourquoi vouloir absolument retourner une référence ? Créer un objet non dynamique et le renvoyer ne convient-il pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // calcule le vecteur entre le point actuel et le point P
    Vecteur3D Point3D::operator- (const Point3D & P)
    {
         Vecteur3D Q(x - P.x, y - P.y, z - P.z);
         return Q; // on retourne une copie de Q
    }
    On peut faire ça en 1 ligne mais bon, c'est juste un exemple ...

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut, et bienvenue sur le forum.

    D'abord, il faut savoir que, le delete apparaissant après l'instruction de retour, il ne sera jamais effectué (un compilateur "correctement réglé" t'aurait sans doute lancé un avertissement du genre "attention, cette instruction ne sera jamais exécutée" )

    Cela provoquera donc, au mieux, une fuite mémoie

    Il serait par contreencore pis d'inverser l'ordre sous la forme de
    parce que tu renverrais alors une référence sur... un objet qui a déjà été détruit (ce qui reviendrait donc au même que si tu n'avais simplement pas eu recours à l'allocation dynamique )

    Ensuite, il faut savoir que l'opérateur - ne devrait pas renvoyer une référence, mais un nouvel objet...

    Les seuls opérateurs qui renvoient une référence (sur le premier opérande de l'opération) sont ayant une composante d'affectation ( =, +=, -=, *=, /= pour être précis), parce que l'objet résultant est... le premier opérande.

    Ainsi, le plus souvent, nous agirons en deux temps:

    1- définir l'opérateur ayant une composante d'affectation comme fonction membre de la classe, renvoyant "ce qui est pointé par this" par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Vecteur3D & Vecteur3D::operator -=(Vecteur3D const & v)
    {
        /* calculer la différence directement sur les membres de this */
        x-=v.x;
        y-=v.y;
        /*...*/
        /* renvoyer l'objet modifié */
        return *this;
    }
    2- définir l'opérateur n'ayant pas de composante d'affectation comme fonction libre qui effectue une copie du premier opérande et renvoie le résultat de l'opérateur équivalent ayant composante d'affectation sur cette copie. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Vecteur3D operator-=(Veceur3D const & v1, Vecteur3D const & v2)
    {
        /* copie de v1 */
        Vecteur3D temp(v1);
        return temp-=v2;
    }
    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

  4. #4
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Bonjour,

    Philosophiquement parlant:
    Citation Envoyé par myzu69 Voir le message
    Pourquoi retourner un Vecteur3D quand tu soustrait deux Point3D ? Je vois bien qu'un vecteur est calculé en soustrayant les coordonnées des deux points extrémités mais j'ai du mal à voir les différences, le code des deux classes est-il différent pour devoir séparer les deux ?
    Mathématiquement, un point et un vecteur sont deux choses bien différentes... On peut donc penser qu'un certain nombre de méthodes soient proposées pour une classe mais pas pour l'autre... N'ayant pas le détail de ces classes, je pense qu'on ne peut juger un tel point.

    Informatiquement parlant:
    En admettant que la classe Vecteur3D soit nécessaire, pourquoi ne pas avoir créé un constructeur qui prend en paramètres les valeurs en x, y et z ?
    Un certain nombre d'APIs et de conventions de codage recommande de limiter les paramètres des constructeurs, et de préferer les passages par 'set' ou par des méthodes d'initialisations... Sa manière d'initialiser ses variables n'est donc pas choquante.

    Enfin pour répondre à ta question, je ne comprends pas pourquoi tu crée un Vecteur3D dynamique, avec ton code, le delete ne sera jamais atteint et l'objet ne sera pas supprimé.
    Totalement d'accord, il y a une fuite de mémoire inquiétante...

    Pourquoi vouloir absolument retourner une référence ? Créer un objet non dynamique et le renvoyer ne convient-il pas ?
    Pour jouer l'avocat du diable, renvoyer une copie peut être couteux... On ne sait pas ce que contient sa classe... Bon là, j'avoue qu'a priori il n'y a que trois nombres à copier, mais par principe je trouve cela moyen...

    Autre question de principe (j'en ai beaucoup!), je trouve dangeureux dans une opération de soustraction que le résultat soit de type différent des paramètres d'entrée...
    Si on a que des éléments du même type voir les solutions de koala01 sinon passer par une méthode avec un nom spécifique du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Vecteur3D* Point3D::CreerVecteurAvec (const Point3D& P);
    // ou sans doute mieux:
    bool Point3D::CreerVecteurAvec (const Point3D& P, Vecteur& V);
    Finish:
    Citation Envoyé par myzu69 Voir le message
    On peut faire ça en 1 ligne mais bon, c'est juste un exemple ...
    ça c'est pas un argument !

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour et bienvenu,
    Quelques éléments complémentaires :
    Strictement parlant, référence ou pointeur : il faut faire attention à la durée de vie de l'objet désignée. Si tu retourne un référence ou un pointeur qui est détruit en fin de fonction (soit explicitement avec ta tentative de delete, soit implicitement sur une variable locale à ta fonction), ta référence ou ton pointeur sont invalides et leur utilisation est indéterminée (généralement un crash au bout d'un moment).
    @fallbot : (pour jouer l'avocat du contre-diable ) un retour par valeur avec une fonction comme Vecteur3D Point3D::CreerVecteurAvec (const Point3D& P)const;, avec un peu de chance, sera optimisé en (N)RVO évitant la copie.

  6. #6
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    @fallbot : (pour jouer l'avocat du contre-diable ) un retour par valeur avec une fonction comme Vecteur3D Point3D::CreerVecteurAvec (const Point3D& P)const;, avec un peu de chance, sera optimisé en (N)RVO évitant la copie.
    Un peu de rigueur que diable !

  7. #7
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    En ce qui me concerne, je procède de cette façon là

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    Point3D *P1; // Un pointeur sur un objet existant
    Point3D *P2; 
    // Maintenant, un veut créer un vecteur V
    // le but étant naturellement de l'utiliser, par exemple pour le comparer
    // à un autre vecteur   
      Vecteur3D *V1=new Vecteur3D(P1, P2);
      ... // traitement
      delete V1;
     
    // La classe Vecteur3D
    class Vecteur3D
    {
      float a, b, c;
    public:
      Vecteur3D {Point3D *p1, Point3D *p2)
      {
        a=p2->x - p1->x;
        b=p2->y - p1->y;
        c=p2->z - p1->z;
      }
    };
    Dernière modification par Invité ; 27/05/2010 à 18h05.

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

Discussions similaires

  1. Retour par référence sur const
    Par Cheps dans le forum C++
    Réponses: 3
    Dernier message: 14/12/2008, 22h36
  2. Retour par référence d'un pointeur
    Par FunkyTech dans le forum C++
    Réponses: 16
    Dernier message: 22/07/2008, 13h56
  3. retour par référence de l'opérateur ++
    Par BigNic dans le forum C++
    Réponses: 4
    Dernier message: 02/08/2006, 18h35
  4. retour d'objet par référence...
    Par sas dans le forum C++
    Réponses: 15
    Dernier message: 28/05/2005, 17h54

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