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

 Delphi Discussion :

Allocation dynamique d'objets


Sujet :

Delphi

  1. #1
    Membre habitué
    Inscrit en
    Septembre 2006
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 254
    Points : 138
    Points
    138
    Par défaut Allocation dynamique d'objets
    Bonjour,

    Après plusieurs années de vagabondage en différents langages, je reviens vers Delphi (delphi 7 en l'occurence sous XP).
    Par analogie avec le C++, je voudrais faire de l'allocation dynamique d'objets.
    D'après les docs trouvées, je devrais pouvoir écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Ppoint := new (PPix,Init(100,100,clRed));
    Bien sûr, Ppoint est un pointeur de type Ppix. PPix est un type pointeur sur TPix qui a Init comme constructeur.
    Or si j'écris cela, j'ai une erreur de compilation "Object type required"
    Si j'écris à la place :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Ppoint := new (PPix);
    Ppoint.Init(100,100,clRed));
    J'ai une erreur à l'exécution "Access Violation at adress ..."

    Quelqu'un pourrait-il me guider sur la voie de la syntaxe correcte ?
    D'avance merci.

    Kim

  2. #2
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 561
    Points : 3 955
    Points
    3 955
    Par défaut
    Ca sent la rouille

    New est une procédure et non une fonction, tu devrais plutôt écrire :
    Ne pourrais-tu pas employer un véritable objet dont le type serait une classe ?

    @+

  3. #3
    Membre habitué
    Inscrit en
    Septembre 2006
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 254
    Points : 138
    Points
    138
    Par défaut Allocation dynamique
    Merci e-ric,

    En effet, ca sent la rouille, mais j'ai essayé la syntaxe que tu préconises. Mêmes effets.

    Par contre, je ne comprends pas ta phrase "Ne pourrais-tu pas employer un véritable objet dont le type serait une classe ?".
    TPix est une classe, PPix un pointeur sur un objet de cette classe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     PPix = ^TPix;
      TPix = class
      canvas : TCanvas;
      public
      X : integer;
      Y : integer;
      color : TColor;
      constructor Init(xi : integer ; yi : integer ; ci : TColor ; can : TCanvas);
      procedure move(dep : integer ; hor : boolean);
      procedure Display;
      procedure Hide;
      end;
    Kim

  4. #4
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 561
    Points : 3 955
    Points
    3 955
    Par défaut
    Le type PPix présente peu d'intérêt car ton type TPix est une classe, les objets instanciés depuis cette classe sont accédés par des références i.e. des pointeurs "domestiqués".

    Le type PPix revient à manier un pointeur de pointeur, ce qui est rarement utile. Je pense que le type TPix devait à l'origine être un objet (object) au sens de Turbo Pascal et la migration vers Delphi avec une classe a été incomplète.

    Le new tel que tu le formules plus tombe en échec car en fait tu alloues de la mémoire pour une référence sur un objet TPix mais pas sur l'objet TPix lui-même. C'est pas la même chose.

    Pour ce faire, il suffit d'invoquer le constructeur depuis la classe, l'allocation de la mémoire est automatique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var
      pix: TPix; // plus de PPix
    begin
      pix := TPix.Init(100,100,clRed); // il manque le paramètre Canvas!!!
    // pix est alloué et initialisé. 
    //...
    Par ailleurs, histoire de rester cohérent avec Delphi, nommes plutôt ton constructeur Create, cela facilitera la compréhension par un autre développeur accoutumé à Delphi.

    @+

  5. #5
    Membre habitué
    Inscrit en
    Septembre 2006
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 254
    Points : 138
    Points
    138
    Par défaut allocation dynamique
    re-merci e-ric,

    Tout va bien maintenant si je ne suis pas dans un environnement graphique.

    Par contre, je mets mon TPix comme donnée d'une Tform.
    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
     
    type
      TForm1 = class(TForm)
        procedure FormPaint(Sender: TObject);
        procedure FormKeyPress(Sender: TObject; var Key: Char);
        procedure FormCreate(Sender: TObject);
        procedure FormKeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
      private
        { Private declarations }
        point : TPix;
        cercle : TCercle;
        Procedure Draw;
      public
        { Public declarations }
      end;
    J'initialise TPix dans FormCreate et J'ai une erreur à l'exécution "Access Violation at adress ...". au moment ou j'appelle le constructeur de TPix.
    Je crois me souvenir qu'il y a justement un problème d'initialisation dans ce cas, mais compte tenu de ce que tu m'as dit précedemment, je ne vois pas pourquoi. (En C++, c'est beaucoup plus simple à comprendre et on met explicitement des pointeurs dans ce cas).

    Si tu as une explicatio et le courage de me la fournir, je t'en remercie d'avance.

    Kim

  6. #6
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 561
    Points : 3 955
    Points
    3 955
    Par défaut
    T'aurais dû mettre le code du FormCreate mais j'ai un doute sur une erreur courante quand on commence (*) ou revient sur Delphi, t'aurais pas des fois écrit un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    procedure TForm1.FromCreate(AOwner: TObject);
    begin
    //...
      point.Init(...);
    //...
    End;
    au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    procedure TForm1.FromCreate(AOwner: TObject);
    begin
    //...
      point := TPix.Init(...);
    //...
    End;
    Les deux écritures sont valides mais la première ne fait qu'appeler le code du constructeur sur l'objet (tu réinitialises l'objet) sans instancier l'objet (pas d'allocation de mémoire). C'est une particularité du constructeur dans Delphi.

    @+
    (*) je l'ai faite et me suis énervé desssus un paquet de fois au début.

  7. #7
    Membre habitué
    Inscrit en
    Septembre 2006
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 254
    Points : 138
    Points
    138
    Par défaut
    Ok, c'était bien ca ...

    Dernier point, si ce n'est pas abuser de ta bonté...

    J'ai défini une classe descedante de Tpix appelée Tcercle.
    Je voudrais définir un variable à laquelle on puisse assigner indiféremment un TPix ou un TCercle. En C++, on prend un pointeur sur l'ancêtre et le tour est joué : selon l'objet pointé, on active automatiquement les bonnes méthodes !
    Mais en Delphi, j'ai essayé de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    current : TPix;
    point : TPix;
    cercle : Tcercle;
    .......
     
    current := point;
    current := cercle;
    Mais je pointe toujours sur un objet de type TPix ....

    Encore tous mes remerciements et mes excuses d'abuser de ton temps

    Kim

  8. #8
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 561
    Points : 3 955
    Points
    3 955
    Par défaut
    Alors là, tu me surprends, Delphi accepte parfaitement le polymorphisme et heureusement. Mais il ne faut pas oublier de déclarer virtuelles les méthodes qui doivent l'être, c'est à dire celles qui vont être invoquées dans du code polymorphique. Cela passe par le mot clé virtual. Dans Delphi, les méthodes sont statiques par défaut.

    Pourrais-tu joindre ton projet dans un zip (en ne mettant que le sources, les dfm et le dpr), s'il n'y a pas trop de travail, j'y apporterais les modifications nécessaires.

    PS : Pas la peine de t'excuser tout le temps, si je participe à ce forum c'est que j'accepte d'aider, sous réserve toutefois que le demandeur d'aide apporte du travail personnel, ce qui semble être le cas.

  9. #9
    Membre habitué
    Inscrit en
    Septembre 2006
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 254
    Points : 138
    Points
    138
    Par défaut
    Désolé, mais ma stricte éducation m'oblige à dire merci et m'excuser en cas de dérangement. Enfin, je veux bien faire un effort pour être moins poli

    En résumé, tu trouveras ci-joint le projet, (qui n'est qu'un projet de test) extrèmement simple, sous réserve que j'ai su l'envoyer correctement, car c'est la première fois que je passe un fichier en PJ sur developpez.com.

    Je ne te dis pas merci pour ne pas te fâcher, mais....

    Kim
    Fichiers attachés Fichiers attachés

  10. #10
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 561
    Points : 3 955
    Points
    3 955
    Par défaut
    Je ne te dis pas merci pour ne pas te fâcher, mais....
    Bon, je vais faire un effort

    Sinon, pour ton problème, c'était presque bon. J'avais oublié de préciser que les méthodes de l'ancêtre doivent être déclarées virtual et celles des descendantes override.

    J'ai annoté ton code (pas beaucoup)
    Fichiers attachés Fichiers attachés

  11. #11
    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 : 55
    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 457
    Points
    28 457
    Par défaut
    la syntaxe que tu proposes dans ton premier message est hérité de Turbo Pascal avec le mot clé "object" qui déclare une classe comme en C++.

    Avec Delphi on passe aux classes avec le mot clé "class" qui a la particularité d'être implicitement un pointer, "object*" pour parler C++

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Test {
    }
    Test t1;
    Test* t2;

    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
      TTest1 = object
        constructor init;
      end;
      PTest1 = ^TTest1;
     
      TTest2 = class
         constructor Create;
      end;
     
    var
      t1 : TTest1; // Test t1a;
      t2 : PTest1; // Test* t1b;
      t3 : TTest2; // Test* t2;
    begin
      t1.init; // t1 est déjà alloué mais non initialisé 
      New(t2, init); // alloue et initialise t2
      t3 := TTest2.Create; // le constructor est une méthode de classe
    end;
    note qu'une classe peut avoir différents constructeurs qui peuvent être virtuels et donc surchargés comment n'importe quelle méthode objet.

  12. #12
    Membre habitué
    Inscrit en
    Septembre 2006
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 254
    Points : 138
    Points
    138
    Par défaut
    Ca y est .... Je suis remis sur les rails (enfin jusqu'au prochain aiguillage).
    C'est vrai que mes souvenirs mélangeaient Delphi et Turbo Pascal, commencé en 1985 (Qui a dit : "à la retraite, papy !" ?, Humm ...) et que mes récentes aventures (en tout bien tout honneur) en C++, PHP, Java et Javascript m'avaient un peu éloigné de l'esprit Borland

    Mais foin de toute nostalgie, merci à tous, notamment à e-ric.

    Kim

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 14/11/2009, 15h49
  2. Réponses: 14
    Dernier message: 26/10/2006, 14h44
  3. Réponses: 9
    Dernier message: 22/12/2005, 22h20
  4. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31
  5. Réponses: 4
    Dernier message: 03/12/2002, 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