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

Lazarus Pascal Discussion :

Comment passer deux objets différents (mais similaires) à une seule procédure ? [Lazarus]


Sujet :

Lazarus Pascal

  1. #21
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 719
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 719
    Points : 15 105
    Points
    15 105
    Par défaut
    Bonjour,

    Merci pour vos retours et explications.
    Deux mots rapides :

    Citation Envoyé par Paul TOTH Voir le message
    autant dire que le mot clé const dans ce cas de figure est rarement utile.
    mais pourtant souvent rencontré : est-ce à dire que son utilité serait de transmettre par référence (juste l'adresse, donc) par exemple une liste non modifiable (une liste où on va aller seulement lire des datas), ce qui sera plus rapide que de recopier toute la liste si l'on omet ce const ?
    Je la sens bien, cette explication,

    Citation Envoyé par Paul TOTH Voir le message
    mais dans la plupart des cas, on n'a besoin ni de "var" ni de "const", et l'objet pointé (le contenu) reste totalement modifiable.
    Oui, mais ça peut être gênant s'il s'agit par ex. d'une grosse vidéo qui va donc se retrouver dupliquée, avec tous les inconvénients liés : temps passé à le faire, occupation mémoire...


    Citation Envoyé par M.Dlb Voir le message
    Pour mieux comprendre, il faut raisonner avec "l'adresse" et "la valeur" d'une variable (peu importe son type).
    Ce qui me choque, là, c'est la fin de la phrase, la partie entre parenthèses, Paul ayant écrit
    Citation Envoyé par Paul TOTH Voir le message
    si TCustomListBox fait l'affaire, il suffit de supprimer le "var" du paramètre pour que cela fonctionne.
    En fait, tout tourne autour de ces 2 phrases du post 14, et voilà l'autre :
    Citation Envoyé par Paul TOTH Voir le message
    "var" n'est nécessaire que si on veut modifier le paramètre lui-même, pas son contenu, et c'est lui qui réclame un type identique.
    Ok, donc var n'est pas nécessaire si je veux modifier le contenu, mais pourrait être utile pour économiser une recopie de datas et une conso mémoire, non ?

    Prenons un exemple :
    Je charge un bmp de travail avec un fichier.bmp, et je veux lui trafiquer les couleurs. J'écrirai donc une function TrafiqueCouleurs(var aBmp: TBitmap): boolean; qui sera appelée par if TrafiqueCouleurs(MonBmpdeTravail) then comme ça je sais si le boulot s'est fait correctement, et j'ai gagné pas mal de temps si on considère que certains fichiers peuvent peser des centaines de Mo (233,7 Mo pour ce Jérome Bosch, 5 vraies minutes pour le charger dans mon Gimp, la machine n'est pas toute jeune...).
    Bon, honnêtement, je n'ai jamais fait de tests, je me contente de faire confiance à ceux qui écrivent ce genre de recommandations.

    En fait, le piège dans lequel j'étais tombé, c'est "et c'est lui qui réclame un type identique" : faudra juste que j'y fasse très attention la prochaine fois.

    Merci à tous et bon dimanche (ouf ! Il fait moins chaud )
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #22
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Prenons un exemple :
    Je charge un bmp de travail avec un fichier.bmp, et je veux lui trafiquer les couleurs. J'écrirai donc une function TrafiqueCouleurs(var aBmp: TBitmap): boolean; qui sera appelée par if TrafiqueCouleurs(MonBmpdeTravail) then comme ça je sais si le boulot s'est fait correctement, et j'ai gagné pas mal de temps si on considère que certains fichiers peuvent peser des centaines de Mo (233,7 Mo pour ce Jérome Bosch, 5 vraies minutes pour le charger dans mon Gimp, la machine n'est pas toute jeune...).
    Bon, honnêtement, je n'ai jamais fait de tests, je me contente de faire confiance à ceux qui écrivent ce genre de recommandations.
    Ben le cas que tu cites est en fait un pointeur, puisque TBitmap est une classe. Donc dans ce cas, c'est l'adresse du pointeur qui est copiée, et tu pourrais modifier le pointeur (par exemple aBmp := nil). Sans var, la valeur du pointeur aBmp sera copiée, et pointera donc au même endroit (c'est-à-dire sur les données du bitmap lui même, que tu pourras modifier aussi).

    En d'autres mots, les données du bitmap ne sont pas dupliqués et peuvent être modifiées, dans les deux cas. A vérifier car je n'ai pas compilateur sous la main.
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  3. #23
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    comme l'indique M.Dlb il faut bien faire la distinction entre les types concernés.

    1) si je déclare par exemple un "array[1..500] of char", c'est un tableau de 500 char, si je le passe avec "var" je peux le modifier, si je le passe sans rien, je peux le modifier, mais c'est en fait une copie du tableau original, donc l'original ne sera pas modifié. Si je le passe en "const" je suis dans le même cas que "var" c'est à dire que j'ai accès directement à l'original mais je n'ai pas le droit de le modifier.

    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
    23
     
    type
      T = array[1..500] of char;
     
    procedure test1(a: T);  // c'est une copie de l'original
    begin
    end;
     
    procedure test2(var a: T); // c'est directement l'adresse de l'original que je peux modifier
    begin
    end;
     
    procedure test3(const a: T); // c'est directement l'original mais il est protégé en écriture
    begin
    end;
     
    var
      aa: T;
    begin
      test1(aa); // crée un copie de aa temporaire !
      test2(aa); // envoie directement aa
      test3(aa); // envoie directement aa
    end;

    2) si j'utilise un pointeur vers un "array[1..500] of char"

    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
    23
    24
    25
    26
    27
    28
     
    var
      T : array[1..500] of char;
      P : ^T;
     
    procedure test1(a: P); // envoie une copie de du pointeur, mais c'est bien le tableau d'origine et il est modifiable
    begin
    end;
     
    procedure test2(var a: P); // envoie le pointer d'origine vers les données d'origine modifiables
    begin
    end;
     
    procedure test3(const a: P); // envoie le pointer d'origine non modifiable vers les données d'origine MODIFIABLES !
    begin
      a^[1] := '!'; // ok
      a := nil; // ne compile pas !
    end;
     
    var
      aa: T;
      pp: P;
    begin
      pp := @aa;
      test1(pp); // envoie une copie de pp qui pointe vers aa
      test2(pp); // envoie directement pp modifiable
      test3(pp); // envoie directement pp non-modifiable, mais aa est modifiable !
    end;
    3) pour toutes les instances de classes, on est implicitement dans le cas d'un pointer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    procedure test1(s: TStringList); // copie du pointeur vers la liste d'origine
    procedure test2(var s: TStringList); // le pointeur d'origine modifiable
    procedure test3(const s: TStringList); // le pointeur d'origine non-modifiable, vers la liste modifiable
    4) et pour les strings c'est entre les deux, car c'est un type particulier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    procedure test1(s: string); // copie de la chaîne complète, pas uniquement une copie du pointeur
    procedure test2(var s:string); // directement le pointeur original modifiable
    procedure test3(const s:string); // directement le pointeur original non modifiable sur une chaîne NON modifiable également
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #24
    Membre chevronné

    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2012
    Messages
    1 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 035
    Points : 2 053
    Points
    2 053
    Par défaut
    1) si je déclare par exemple un "array[1..500] of char", c'est un tableau de 500 char, si je le passe avec "var" je peux le modifier, si je le passe sans rien, je peux le modifier, mais c'est en fait une copie du tableau original, donc l'original ne sera pas modifié. Si je le passe en "const" je suis dans le même cas que "var" c'est à dire que j'ai accès directement à l'original mais je n'ai pas le droit de le modifier.
    Si je comprend bien ceci avec var je peux changer le contenu d'une variable dans une procédure comme je le ferais dans une fonction avec un result. La différence sera que la variable sera modifiée au cours de l'exécution de la procédure alors que dans l'autre cas elle ne le sera qu'une fois la fonction totalement accomplie ?

  5. #25
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par mm_71 Voir le message
    Si je comprend bien ceci avec var je peux changer le contenu d'une variable dans une procédure comme je le ferais dans une fonction avec un result. La différence sera que la variable sera modifiée au cours de l'exécution de la procédure alors que dans l'autre cas elle ne le sera qu'une fois la fonction totalement accomplie ?
    en fait Result c'est un cas particulier :

    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
     
    function test1: T;
    begin
      Result := ...
    end;
     
    procedure test2(var A: T);
    begin
      A := ...
    end;
     
    var
      AA: T;
      tmp: T;
    begin
      AA := test1; // le cas du Result est équivalent en code ci-dessous
     
      test2(tmp); // Result est équivalent à une variable temporaire
      AA := tmp;  // elle est copiée après l'appel, ce qui n'est pas optimum pour un array[1..500] of char :)
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #26
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Merci, c'est gentil mais ça ne m'explique pas concrètement la différence entre le paramètre et le contenu du paramètre.
    C'est la différence qu'il y a entre :
    Modifier sur un post-it (généralement un petit papier jaune avec une bande adhésive), l'adresse que vous aurez inscrite d'une maison,
    et
    Apporter des modifications à la maison elle-même, comme par exemple refaire la façade ou construire un 3ème étage.

    C'est quand même pas pareil non ?

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 2
    Dernier message: 28/03/2016, 15h51
  2. [RCP][débutant] Comment passer un objet d'une vue à une autre
    Par jycronier dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 20/07/2006, 15h13
  3. Réponses: 4
    Dernier message: 20/04/2006, 11h07
  4. [JACOB] Comment passer un objet par référence à une méthode
    Par zlavock dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 21/03/2005, 18h28

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