Erreur de compatibilité

Signaler
Messages postés
3
Date d'inscription
dimanche 2 décembre 2007
Statut
Membre
Dernière intervention
2 décembre 2007
-
Messages postés
1023
Date d'inscription
dimanche 1 août 2004
Statut
Membre
Dernière intervention
17 août 2008
-
Bonjour,

Je suis nouveau en Delphi, et même sur ce site.

J'ai un problème à la compilation de mon programme.
Il conciste à créer des éléments de type TAnimaux (polymorphisme) et à les insérer dans une liste chaînée simple.

Le code:

unit U_Animaux;



interface



uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;



type
  TForm1 = class(TForm)
    Memo1: TMemo;
    RadioBtnOiseau: TRadioButton;
    RadioBtnChien: TRadioButton;
    BtnAfficher: TButton;
    BtnQuiter: TButton;
    BtnEffacer: TButton;
    BtnCreate: TButton;
    procedure BtnAfficherClick(Sender: TObject);
    procedure BtnEffacerClick(Sender: TObject);
    procedure BtnQuiterClick(Sender: TObject);
    procedure BtnCreateClick(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;




 



var
  Form1: TForm1;



implementation



{$R *.dfm}



uses
  U_Oiseaux, U_Chien, U_Animal;



type
  TPtrAnimaux = ^TAnimaux;
  TAnimaux = record
    animal : string;
    action : string;
    suivant : TPtrAnimaux;
  end;



var
  premier, dernier : TPtrAnimaux;
  a : TAnimal;



// Créer
procedure TForm1.BtnCreateClick(Sender: TObject);
begin
  if RadioBtnOiseau.Checked = true then
  begin
    a := TOiseau.Create;
  end
  else if RadioBtnChien.Checked = true then
  begin
    a := TChien.Create;
  end;



  if premier = nil then
  begin
    new(premier);
    dernier := premier;
  end
  else
  begin
   new(dernier^.suivant);
   dernier := dernier^.suivant;
  end;



  //if RadioBtnOiseau.Checked := true then
  //begin
    dernier^.animal := a.manger;
    dernier^.action := a.deplacer;
  //end
  //else if RadioBtnChien.Checked := true then
  //begin
  //  dernier^.animal := a.manger;
  //  dernier^.action := a.deplacer;
  //end;



  dernier^.suivant := nil;
end;



// Afficher
procedure TForm1.BtnAfficherClick(Sender: TObject);
var
  parcours : TPtrAnimaux;
begin
  memo1.clear;
  parcours := premier;
  while parcours <> nil do
  begin
    memo1.Lines.Add(a);
    parcours := parcours^.suivant;
  end;
end;



// Effacer
procedure TForm1.BtnEffacerClick(Sender: TObject);
var
  ptrSave : TPtrAnimaux;
begin
  while ptrSave <> nil do
  begin
    ptrSave := premier^.suivant;
    Dispose(premier);
    premier := ptrSave;
  end;
  dernier := nil;
end;



// Quitter
procedure TForm1.BtnQuiterClick(Sender: TObject);
begin
  application.terminate;
end;



end.


Il y a encore 3 autres unités mais j'ai pensé qu'elles n'étaient pas utiles pour ma question qui est la suivante:

J'ai une erreur à la compilation qui me dit que je ne peux pas afficher qqch de type TAnimal dans le memo1. Je conçoit tout à fait, par contre, je ne sais pas comment le faire !?

Merci d'avance à celui qui pourra m'aider à me sortir de ce petrin.. (Je viens déja de passer 3heures à faire rien que cela.. c'est la cata !!  lol)

@+

SteveBru

7 réponses

Messages postés
1725
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
11 avril 2021
8
Salut,

Tu oublies de nous décrire le type TAnimal.
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
18
Salut,

Sans connaître le type TAnimal, on peut lui conseiller ça:

Dans ta procedure "


procedure TForm1.BtnAfficherClick(Sender: TObject);"
à la ligne "




memo1.Lines.Add(a);"
tape un point après le "a" de "Add(a)".
Normalement, tu devrais avoir un choix des champs de TAnimal acceptés par le Memo.
Messages postés
3
Date d'inscription
dimanche 2 décembre 2007
Statut
Membre
Dernière intervention
2 décembre 2007

Merci pour les réponses rapides !

Alors je vais vous joindre les autres unités:

Unité 'U_Oiseaux':

unit U_Oiseau;



interface



uses
  U_Animal;



type
  TOiseau = class(TAnimal)
  public
    function manger : string; override;
    function deplacer : string; override;
  end;



implementation



{ TOiseau }



function TOiseau.deplacer: string;
begin
  result := 'L''oiseau mange des graines';
end;



function TOiseau.manger: string;
begin
  result := 'Par contre, l''oiseau vole!';
end;



end.



-------------------------

Unité 'U_Chien':

unit U_Chien;



interface



uses
  U_Animal;



type
  TChien = class(TAnimal)
  public
    function manger : string; override;
  end;



implementation



{ TChien }



function TChien.manger: string;
begin
  result := 'Le chien mange des os';
end;



end.

 --------------------

Unité 'U_Animal':

unit U_Animal;



interface



type
  TAnimal = class
  public
    function manger : string; virtual; abstract;
    function deplacer : string; virtual;
  end;



implementation



{ TAnimal }



function TAnimal.deplacer: string;
begin
  result := 'Les animaux se déplacent en marchant';
end;



end.



Voilà, j'espère que vous pourrez m'aider, par contre, Caribensila, ta réponse n'a pas marché.. (merci quand même  ).
Messages postés
3
Date d'inscription
dimanche 2 décembre 2007
Statut
Membre
Dernière intervention
2 décembre 2007

...au fait, pouvez-vous m'indiquer l'utilité "d'accepter les réponses" ?


merci ^^
Messages postés
1725
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
11 avril 2021
8
A priori tu ne peux pas accéder aux méthodes de TAnimal puisque elles sont abstract.
Il te faut instancier une classe qui en hérite (par exemple TChien).

var a: TChien
  memo1.Lines.Add(a.manger); // par exemple

J'ai décoché les réponses acceptées.
Il ne faut les cocher que quand la réponse apporte la solution, au moins en partie. Sinon personne ne viendra sur le topic, le pensant résolu.
Messages postés
1725
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
11 avril 2021
8
Zut, je me relis et je m'aperçois que j'ai fait une erreur...

C'est :

 Memo1.Lines.Add(a.deplacer)

puisque tu ne peux accéder à TAnimal.manger qui est une méthode abstraite.
Messages postés
1023
Date d'inscription
dimanche 1 août 2004
Statut
Membre
Dernière intervention
17 août 2008
2
Salut !

Quand tu fais cela:

<hr size= "2" width="100%" />  while parcours <> nil do
  begin
    memo1.Lines.Add(a);
    parcours := parcours^.suivant;
  end;
<hr size="2" width="100%" />
Tu parcours toute ta liste chaînée, mais "a" (la variable) reste la même ! Y'a comme un problème quelque part (d'où le danger des variables globales...)

De plus, comme le signale Caribensila, le type TAnimal n'est pas acceptable par un mémo, qui ne veut que des strings, donc, dans ton cas, a.déplacer ou a.manger, à condition que ces méthodes existent dans l'objet que tu as crée.

Voyant ce bout de code, je te propose deux solutions (faire soit l'une, soit l'autre, et pas un mix des deux !):
<hr size="2" width="100%" />    dernier^.animal := a.manger;
    dernier^.action := a.deplacer;
<hr size="2" width="100%" />
I- Première solution: la plus simple (mais de loin celle que j'aime le moins).

Remplacer memo1.Lines.Add(a); par memo1.Lines.Add(parcours^.animal)
(ou bien par parcours^.action).

II- Deuxième solution: plus complexe, mais bien plus souple et puissante
<ol><li>Supprimer ta variable globale a
</li><li>La mettre en local dans la procédure BtnCreateClick().</li><li>Supprimer ce bout de code:</li></ol>  //if RadioBtnOiseau.Checked := true then
  //begin
    dernier^.animal := a.manger;
    dernier^.action := a.deplacer;
  //end
  //else if RadioBtnChien.Checked := true then
  //begin
  //  dernier^.animal := a.manger;
  //  dernier^.action := a.deplacer;
  //end;

    4. Changer le type TAnimaux en

TAnimaux = record
    animal : TAnimal; // Comme ça, tu as accès à tout l'objet d'un seul coup !
    suivant : TPtrAnimaux;
  end;

    5. A l'endroit où je t'ai fait supprimer l'autre bout, mettre ceci : dernier^.animal : = a
    6. Avant cette ligne (Dispose(premier);), mettre le bon code de libération: premier^.animal.Free;
    7. Et finalement, remplacer memo1.Lines.Add(a); par memo1.Lines.Add(parcours^.animal.manger) [ou déplacer suivant ce que tu veux faire]

Perso, je te recommande la deuxième solution, ça te permettra d'aller plus vite dans le reste de ton projet.

A+
Flo

Ressources Delphi, sources, tutoriaux, actu, ...: www.mx-dev.net