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

Langage Delphi Discussion :

Utilisation des pointeurs


Sujet :

Langage Delphi

  1. #1
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut Utilisation des pointeurs
    Bonjour à tous,
    J'utilise de plus en plus souvent des pointeurs vers des Record pour stocker mes données, et je souhaite simplifier un peu mes applications.

    Si je déclare les 3 records suivants, pour pouvoir faire pointer pRecordC.eCible vers un pCibleA ou pCibleB

    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
     
    Type
      pCibleA = ^tCibleA;
     
      tCibleA = record
        // ...
      end;
     
      pCibleB = ^tCibleB;
     
      tCibleB = record
        // ...
      end;
     
      pRecordC = ^tRecordC;
     
      tRecordC = record
        eTypeCible: byte;
        eCible: pointer;
      end;
    Jusqu'à présent, je mémorise dans pRecordC.eTypeCible une valeur en relation avec la cible réelle, ce qui me permet, à l'utilisation, de "reverser" mon pointer dans une variable du bon type.

    Y a-t-il une possibilité pour éviter cette mémoire, de savoir si, après initialisation, eCible est un pointer de type A ou B ?

    J'ai trouvé ceci :
    https://stackoverflow.com/questions/...e-of-a-pointer
    mais je tente tout de même ma chance...

    Merci pour votre aide.
    Belle soirée,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  2. #2
    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
    il y a une raison pour laquelle tu utilises des record au lieu de classes ?

    sinon sauf à avoir le champ eTypeCible dans TCible*, il n'y a pas de solution
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    il y a une raison pour laquelle tu utilises des record au lieu de classes ?

    sinon sauf à avoir le champ eTypeCible dans TCible*, il n'y a pas de solution

    Depuis TurboPascal, je développe (en autodidacte) des "outils" qui me permettent, dans mon activité professionnelle, d'automatiser des fonctions. Comme le but est de gagner du temps, je prends plus souvent (trop), les chemins connus que les meilleurs.
    J'ai ce problème de pointeur en utilisant souvent le VirtualTreeView pour présenter des données efficacement. Comme ces données sont hiérarchisées, chaque noeud peut pointer sur une donnée de type très variable, c'est pourquoi je passe par un enregistrement intermédiaire, qui, lui, peut me renvoyer vers la bonne donnée.
    Ma dernière appli commence à être un peu complexe, c'est pourquoi, une bonne remise en cause serait surement profitable.

    Merci pour ta réponse,
    Cordialement,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  4. #4
    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
    alors, la programmation objet n'est pas intuitive, c'est un concept qu'il faut intégrer avant de savoir s'en servir...je me souviens très bien qu'à l'époque de Turbo Pascal 5.5 (introduction de l'objet dans Turbo Pascal) j'ai commencé à regarder et je me suis demandé à quoi ça pouvait bien servir vu que ça ne m'apportait rien de créer un objet TMouse pour gérer la souris via le port COM (et oui sous DOS !) alors que j'avais depuis longtemps un record TMouse avec quelques fonctions associées qui faisait aussi bien le taf.

    et en effet, dans le cas de cette souris, ça n'apportait pas grande chose de faire Mouse.Show() au lieu de ShowMouse(Mouse)

    mais ce qui est intéressant dans ton cas, c'est que tu fais déjà de la programmation orientée objet, sauf que tu n'utilises pas des objets

    tu as un pointeur qui peut pointer sur différents record et tu as besoin de savoir quel type de record c'est...et bien un objet c'est exactement cela.
    j'ai écris il y a longtemps une présentation des objets et des classes
    http://tothpaul.free.fr/tips.php?pv_object
    http://tothpaul.free.fr/tips.php?pv_class

    par exemple, au lieu de faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    begin
      case pRecordC(Node.Data).eTypeCible of
        A : pCibleA(pRecordC.eCible).Click;
        B:  pCibleB(pRecordC.eCible).Click;
      end;
    end;
    tu peux juste faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      TRecordC(Node.Data).Click;
    pour cela il faut juste créer les objets suivant ce shéma

    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
     
    type
      TRecordC = class
        commun: Integer;
        procedure Click; virtual; abstract; 
       end;
     
      TCibleA = class(TRecordC)
        pourA: Integer;
        procedure Click; override;
      end;
     
      TCibleB = class(TRecordC)
        PourB: Integer;
        procedure Click; override;
      end;
     
    procedure TClibA.Click;
    begin
      if (PourA = 1) and (Commun = 2) then...
    end;
     
    procedure TClibB.Click;
    begin
      if (PourB = 2) and (Commun = 3) then...
    end;
    dans cet exemple, on a donc un objet de base TRecordC qui sert juste à déclare une donnée commune à tous les record, plus une méthode Click virtuelle (elle peut être modifiée par les descendants) et abstraite (elle n'existe pas au niveau de TRecordC, si un enfant ne la surcharge pas, un appel provoquera une erreur d'execution)

    les classes ClickA et B ajoutent une donnée spécifique PourA/B et définissent le comportement de la classe quand on appelle la méthode Click

    techniquement, la classe possède simplement une VMT (table de méthode virtuelle) qui dans notre exemple contient simplement le pointeur vers la bonne version de Click
    on pourrait faire la même chose sans objet avec des records

    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
     
    type
      PRecordC = ^TRecordC;
      TRecordC = record
        Click: procedure(Sender: PRecordC);
        Commun: Integer;
      end;
     
      PClickA = ^TClickA;
      TClickA = record
        C: TRecordC;
        PourA: Integer;
      end;
     
    procedure TClickAClick(Sender: PRecordC);
    begin
      if (Sender.Commun = 1) and (PClickA(Sender).PourA = 2) then...
    end;
    ...
    var
      A: TClickA;
    begin
      A.Click := TClickAClick; // initialisation de "l'objet"
    end;
    voilà, en gros ça donne ça, le record TClickA contient le record TRecordC et on stocke l'adresse de la procédure TClickAClick dedans...sauf qu'avec des objets c'est automatique et qu'on utilise une VMT donc toutes les instances de TClickA pointent sur la même table de méthodes au lieu de contenir la liste de toutes les méthodes virtuelles

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    type
      PVMT = ^TVMT;
      TVMT = record
        procedure Click(Sender: Pointer);
      end;
      TRecordC = record
        VMT: PVMT;
      end;
     
    const
      TVMT_ClickA : TVMT = (click: TClickA_Click);
    ça tu ne le lira pas dans les bouquin sur la POO car c'est de la technique (c'était décrit dans les bouquin de Turbo Pascal !) et pas du concept...mais personnellement je trouve que c'est plus simple de comprendre la programmation orientée objet quand on sait comment ça fonctionne
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut
    Merci Paul pour ces explications on ne peut plus claires.
    Je vais consulter tes tutos avant de regarder ce que je peux, rapidement mettre en application...et surtout revoir dans les prochains projets.

    Au début, j'ai effectivement abordé la POO avec un certain recul, notamment à cause de la notion d'évènement qui provoque une 'non-continuité' dans l'exécution du code. Pour avoir aussi programmé en code machine (hexa) puis en assembleur, la notion de pointeur qui semble énigmatique pour certains, est assez simple dans mon cas.

    En tout cas, merci pour ce petit cours particulier..
    La belle journée à tous,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

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

Discussions similaires

  1. utilisation des pointeurs de type "far"
    Par Flow_75 dans le forum C++
    Réponses: 0
    Dernier message: 25/03/2008, 07h35
  2. utilisation des pointeurs
    Par OutOfRange dans le forum Delphi
    Réponses: 5
    Dernier message: 27/12/2006, 11h27
  3. utilisation des pointeur
    Par nixonne dans le forum Langage
    Réponses: 2
    Dernier message: 25/08/2006, 09h19
  4. Optimiser l'utilisation des pointeurs
    Par progfou dans le forum C
    Réponses: 65
    Dernier message: 10/03/2006, 11h49
  5. Réponses: 6
    Dernier message: 21/02/2006, 16h47

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