Probleme de lecture

Signaler
Messages postés
23
Date d'inscription
jeudi 17 juin 2004
Statut
Membre
Dernière intervention
6 décembre 2007
-
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
-
Bonjour à tous,
voila, je débute en delphi et je suis en train de faire quelque tests de prog.
version de delphi utilisée : Delphi 7 personnal edition.
j'ai actuellement un problème de lecture en mémoire,
lorsque j'execute une des fonctions de mon appli, j'ai le message suivant qui apparaît :
(il est bien connu c'est un probleme que beaucoup de personnes rencontrent d'après ce que j'ai vu)
"Project Project1.exe raised exception class EAccessViolation with message 'Access violation at adresse.........etc etc..'Process Stopped. Use step or run to continue."

en fait dans ce prog je veux creer une liste
(je sais qu'il existe la classe Tlist, Tobjectlist et tout et tout mais je veux faire à ma manière)

j'ai 2 units :

la première :

unit liste_joueurs;

interface
uses classes;

type
//classe Cjoueurs, contenant le nom, prenom et pseudo de la personne
  Cjoueurs = class
    public
      Nom:String;
      Prenom:String;
      Pseudo:String;
      //le constructeur de la classe
      constructor create_j(n:String;p:String;s:String);
      //les fonctions de récupération
      function get_Nom:String;
      function get_Prenom:String;
      function get_Pseudo:String;
      //les fonctions de modification
      procedure set_Nom(n:String);
      procedure set_Prenom(p:String);
      procedure set_Pseudo(s:String);

end;

//ma classe maillon qui contiendra un objet de type Cjoueur
//et un objet de type maillon
maillon = class
  public
    suivant:maillon;
    joueur:Cjoueurs;
    constructor maillons();
end;

//classe liste_chainee qui contiendra le maillon tete de ma liste
//le dernier maillon de la liste
//et une fonction d'ajout
liste_chainee = class
  public
    tete:maillon;
    dernier:maillon;
    constructor liste_c();
    procedure ajout();
end;

implementation
//constructeur de Cjoueurs
constructor Cjoueurs.create_j(n:String;p:String;s:String);
begin
  Nom:=n;
  Prenom:=p;
  Pseudo:=s;
end;

function Cjoueurs.get_Nom:String;
begin
  get_Nom:=Nom;
end;

function Cjoueurs.get_Prenom:String;
begin
  get_Prenom:=Prenom;
end;

function Cjoueurs.get_Pseudo:String;
begin
  get_Pseudo:=Pseudo;
end;

procedure Cjoueurs.set_Nom(n:String);
begin
  Nom:=n;
end;

procedure Cjoueurs.set_Prenom(p:String);
begin
  Prenom:=p;
end;

procedure Cjoueurs.set_Pseudo(s:String);
begin
  Pseudo:=s;
end;

//-------------------------------------------------------------------------
//classe maillon
constructor maillon.maillons();
begin
  joueur:=Cjoueurs.Create;
  suivant:=maillon.Create;
end;

//-------------------------------------------------------------------------

constructor liste_chainee.liste_c();
begin
  tete:=maillon.maillons();     //on créé les deux maillons
  dernier:=maillon.maillons();
end;

procedure liste_chainee.ajout();
begin
  tete.joueur.create_j('az','er','ty');
  tete.suivant:=dernier;
end;

end.

et la deuxieme toute bête :

unit testlist;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  liste:liste_chainee;
  sr:String;

implementation
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
liste.ajout();
sr:=liste.tete.joueur.get_Nom();
showmessage(sr);
end;

end.

Voila, qu'est ce qu'il y à comme grosses erreurs et qui fait que ca ne marche pas ?
(ps : c'est une adaptation de ce que j'ai fais pour un projet en java.)

5 réponses

Messages postés
120
Date d'inscription
mardi 3 avril 2007
Statut
Membre
Dernière intervention
15 novembre 2007
1
bjr

je pense qu'il manque la ligne suivante dns ton constructor:

inherited create;


J-L
Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
c'est pas juste un probleme d'inheritance ...

je vais enumerer tout les problemes de ton code :

- non respect des conventions Delphi en matiere de syntaxe et d'identification des classes/variables etc
- creation d'objets incontrolé, hasardeuse
- aucune liberation d'objet alloué
- aucun control d'assignation / allocation
- methode redondante et inutile
- constructeur inutile et mal declaré
- pas de destructeur
- adaptation d'un code java donc forcement incompatible avec un langage de programmation ordonné et puissant

tu
dis ne pas vouloir deriver un TList ou TObjectList ... ce serait
pourtant la meilleure solution, parsque les liste chainées ça pue,
c'est pas souple, pas pratique et ça chie toujours au bout d'un moment
surtout quand un maillon saute :

type
  { TPlayer }
  TPlayer = class(TObject)
  private
    fName      : string;
    fSurname   : string;
    fNickname  : string;
    fPrecedent : TPLayer;
    fFollowing : TPlayer;
  public
    constructor Create;
    property Name     : string read fName     write fName;
    property Surname  : string read fSurname  write fSurname;
    property Nickname : string read fNickname write fNickname;
    property Precedent: TPlayer read fPrecedent write fPrecedent;
    property Following: TPlayer read fFollowing write fFollowing;
  end;

  { TPlayerList }
  TPlayerList = class(TList)
  protected
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;
    function GetItem(Index: Integer): TPlayer;
    procedure SetItem(Index: Integer; APlayer: TPlayer);
  public
    constructor Create; overload;
    function First : TPlayer;
    function Last : TPlayer;
    property Items[Index: Integer]: TPlayer read GetItem write SetItem; default;
    function Add(const AName, ASurname, ANickname : string) : Integer;
    function Add(APlayer: TPlayer): Integer;
    procedure Insert(Index: Integer; APlayer: TPlayer);
    function IndexOf(APlayer: TPlayer): Integer;
    function Extract(APlayer: TPlayer): TPlayer;
    function Remove(APlayer: TPlayer): Integer;
  end;

{ TPlayerList }

function TPlayerList.Add(APlayer: TPlayer): Integer;
begin
  Result := inherited Add(APlayer);
end;

function TPlayerList.Add(const AName, ASurname, ANickname: string): Integer;
var VPlayer : TPlayer;
begin
  VPlayer := TPlayer.Create;
  with VPlayer do
  begin
    Name    := AName;
    Surname := ASurname;
    Nickname:= ANickname;
  end;
  result := inherited Add(VPlayer);
end;

constructor TPlayerList.Create;
begin
  inherited Create;
  fFindIndex := -1;
end;

function TPlayerList.Extract(APlayer : TPlayer): TPlayer;
begin
  Result := TPlayer(inherited Extract(APlayer));
end;

function TPlayerList.First: TPlayer;
begin
  Result := TPlayer(inherited First);
end;

function TPlayerList.GetItem(Index: Integer): TPlayer;
begin
  Result := inherited Items[Index];
end;

function TPlayerList.IndexOf(APlayer: TPlayer): Integer;
begin
  Result := inherited IndexOf(APlayer);
end;

procedure TPlayerList.Insert(Index: Integer; APlayer: TPlayer);
begin
  inherited Insert(Index, APlayer);
end;

function TPlayerList.Last: TPlayer;
begin
  Result := TPlayer(inherited Last);
end;

procedure TPlayerList.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if Action = lnDeleted then
     TPlayer(Ptr).Free;
  inherited Notify(Ptr, Action);
end;

function TPlayerList.Remove(APlayer: TPlayer): Integer;
begin
  Result := inherited Remove(APlayer);
end;

procedure TPlayerList.SetItem(Index: Integer; APlayer: TPlayer);
begin
  inherited items[Index] := APlayer;
end;

{ TPlayer }

constructor TPlayer.Create;
begin
  fName     := '';
  fSurname  := '';
  fNickname := '';
end;

fait en deux secondes, et t'as plus qu'a adapter pour tes besoin.

dernier conseil :

quand tu programme en Delphi, oublis (presque) tout ce que tu as apris en Java!
quand
tu as besoin d'un objet verifie qu'il n'existe pas deja ou du moins
qu'une base n'existe pas deja, n'hesite pas a la derivée, l'adaptée a
tes besoins, on perd souvent trop de temps a vouloir utiliser des
methodes personnelle non eprouvée, bancale, peu adaptable, pas souple
et au final presque infonctionnelle, crois moi ... faut pas chercher a
réinventer la roue.

<hr size="2" width="100%" />Croc (click me)
Messages postés
23
Date d'inscription
jeudi 17 juin 2004
Statut
Membre
Dernière intervention
6 décembre 2007

Merci bien pour ces conseils
j'ai à peu près vu tout ce qui n'allait pas je vais essayer de refaire ce que tu as mis sans le regarder histoire de bien comprendre.
et merci pour la réponse rapide ;)
Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
sinon pour ton code, l'une des principales faille ou plutot principal defaut reside dans l'allocation et liberation d'instance d'objet.
on vois danblé que ton code provoque une importante fuite memoire puisqu'a aucuns moment les objet créés ne sont pas libéré.
sans parler du fait, comme je l'ai deja dis, que les listes chainées c'est un truc archaique qui ne serat jamais aussi souple qu'une belle liste bien ordonée qui fera office de chaine avec la capacitée d'etre facilement modifiée.

<hr size="2" width="100%" />Croc (click me)
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
14
bravo foxi pour cette démonstration et j'en profite pour donner deux liens à
darkthief :

http://membres.lycos.fr/lesdelphistes/poo.html
http://fbeaulieu.developpez.com/guide/14-objets-2.html

qui me semblent intéressants afin de comprendre la création d'objets, de classes dérivées et la notion d'héritage.
@foxi :
Autre sujet: que penses-tu de la programmation en JAVA, ses avantages, ses inconvénients aussi bien pour traiter une appli Web Serveur que Client Serveur ou autre chose ?

je souhaiterais vivement (et peut-être d'autres aussi..) avoir ton sentiment sur la question.

merci et à bientôt
cantador