Urgent : besoin d'aide svp : EACESSVIOLATION

Résolu
loic38760 Messages postés 48 Date d'inscription samedi 16 octobre 2004 Statut Membre Dernière intervention 22 juin 2009 - 16 oct. 2004 à 14:35
loic38760 Messages postés 48 Date d'inscription samedi 16 octobre 2004 Statut Membre Dernière intervention 22 juin 2009 - 16 oct. 2004 à 16:37
Je suis novice en Delphi et c'est le premier programme que j'écris je ne connais donc pas grand chose.

Mon problème est que lorsque j'essaye d'executer une fonction dans un timer il apparait ce message : "Le projet...aprovoqué une classe d'exception Eaccessviolation avec le message Viloation d'accés à l'adresse...dans le module...Lecture de l'adresse...".

J'ai beau cherché je ne comprends pas pourquoi ca ne marche pa (jai delphi 7) est ce que quelqu'un pourrait m'aidé svp ?

voila mon code :

unit Unit2;

interface

//Déclaration du Type compte
type
compte=class

private
solde : double;
Num_cpte : integer;
nom : string;

public
constructor create (n:integer;x:string);
procedure crediter (m:double);
procedure debiter (m:double);
function solde_compte() : double;
end;

//Déclaration du type codevi
type
codevi=class(compte)

private
num_cptecv : integer;
taux : integer;
soldecv: double;

public
constructor create (n:integer; x:string);
function incrementer() : double;
end;

.......................

function codevi.incrementer() : double;
begin
soldecv:=soldecv+50; (L'ERREUR EST LA)
soldecv:=soldecv*(1+taux/100);
incrementer:=soldecv;
end;

.......................

/Timer Codevi
procedure TForm1.Timer1Timer(Sender: TObject);
var resultat : string;
begin
str(cv.incrementer:10:2, resultat);
Memo.text:=resultat;
end;

8 réponses

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
16 oct. 2004 à 16:24
Je pense que cela provient du fait que ta variable cv n'est pas encore instanciée quand le timer se déclenche.
Pour éviter cela, tu peux tester si cv est déjà créé comme ceci et, si c'est le cas, tu peux appliquer le traitement :
/Timer Codevi
procedure TForm1.Timer1Timer(Sender: TObject);
var resultat : string;
begin
  //si CV n'est pas encore instancié, on passe...
  if Assigned(CV) then
  begin
    str(cv.incrementer:10:2, resultat);
    Memo.text:=resultat; 
  end;
end; 


Au vu du code que tu donnais, il était impossible de deviner si le timer était actif au démarrage et quelle était la valeur de sa propriété Interval.
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you
3
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
16 oct. 2004 à 14:47
Il ne suffit pas de déclarer une classe pour qu'elle soit instanciée.
Au vu du code ci-dessus, tu essaies d'utiliser des objets qui n'ont pas été créés.

Un petit conseil qui pourrait t'éviter ce genre de problèmes : respecter les conventions de nommage standard, c'est à dire préfixer tes classes avec la lettre T pour signifier qu'il s'agit d'un Type :
Ex:
type
  TCompte = class
   //...
  end;

  TCodevi = class(TCompte)
   //...
  end;

ensuite, tu déclares des variables objets du type dont tu as besoin :
var
  Compte: TCompte;
  Codevi: TCodevi;


Ainsi, tu aurais tout de suite vu que les méthodes ne pouvaient pas s'appliquer à une classe mais à une instance et le problème aurait été détecté dès la phase de compilation.
Ce n'est pas pour faire plus joli que Borland a adopté cette convention de nommage.

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you
0
loic38760 Messages postés 48 Date d'inscription samedi 16 octobre 2004 Statut Membre Dernière intervention 22 juin 2009
16 oct. 2004 à 14:53
d'accord merci de m'expliquer ca je débute et il y a certaines choses auquelles je ne fesait pas attention, je vais essayer.
0
loic38760 Messages postés 48 Date d'inscription samedi 16 octobre 2004 Statut Membre Dernière intervention 22 juin 2009
16 oct. 2004 à 15:07
j'ai effectué ces modifications mais le meme problème reste toujours et je ne vois pas ce qui cloche, voila mon code en entier, merci de m'aider si vous voyez ce qui cloche !

unit Unit2;

interface

//Déclaration du Type compte
type
Tcompte=class

private
solde : double;
Num_cpte : integer;
nom : string;

public
constructor create (n:integer;x:string);
procedure crediter (m:double);
procedure debiter (m:double);
function solde_compte() : double;
end;

//Déclaration du type codevi
type
Tcodevi=class(Tcompte)

private
num_cptecv : integer;
taux : integer;
soldecv: double;

public
constructor create (n:integer; x:string);
function incrementer() : double;
end;

implementation

constructor Tcodevi.create (n:integer; x:string);
begin
num_cptecv:=n;
nom:=x;
soldecv:=50;
taux:=3;
end;

constructor Tcompte.create(n:integer;x:string);
begin
Num_cpte:=n;
nom:=x;
solde:=0;
end;

procedure Tcompte.crediter (m:double);
begin
solde:=solde+m;
end;

procedure Tcompte.debiter (m:double);
begin
solde:= solde - m;
end;

function Tcompte.solde_compte(): double;
begin
solde_compte :=solde;
end;

function Tcodevi.incrementer() : double;
begin
soldecv:=soldecv+50;
soldecv:=soldecv*(1+taux/100);
incrementer:=soldecv;
end;

end.

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Label1: TLabel;
Nom: TEdit;
Label2: TLabel;
Num_cpte: TEdit;
Label3: TLabel;
Num_cod: TEdit;
Label4: TLabel;
Button1: TButton;
Label5: TLabel;
Montant: TEdit;
Label6: TLabel;
RadioGroup1: TRadioGroup;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
Label7: TLabel;
sld: TEdit;
Button2: TButton;
Button3: TButton;
Memo: TMemo;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;

var
Form1: TForm1;
Compte: Tcompte;
Codevi: Tcodevi;

implementation

{$R *.dfm}

//Bouton Créer le compte
procedure TForm1.Button1Click(Sender: TObject);
begin
compte:= compte.create (StrtoInt(Num_cpte.Text),Nom.text);
codevi:= codevi.create (Strtoint(Num_cod.Text),Nom.Text);
ShowMessage('Compté crée')
end;

//Bouton Effectuer une opération
procedure TForm1.Button3Click(Sender: TObject);
begin
If RadioButton1.Checked
then compte.crediter(strtoint(montant.text))
else compte.debiter(strtoint(montant.text))
end;

//Bouton Consulter le solde du compte
procedure TForm1.Button2Click(Sender: TObject);
var resultat : string;
begin
str(compte.solde_compte:10:2, resultat);
sld.Text:=resultat;
end;

//Timer Codevi
procedure TForm1.Timer1Timer(Sender: TObject);
var resultat : string;
begin
str(codevi.incrementer:10:2, resultat);
Memo.text:=resultat;
end;

end.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
loic38760 Messages postés 48 Date d'inscription samedi 16 octobre 2004 Statut Membre Dernière intervention 22 juin 2009
16 oct. 2004 à 15:08
au fait je precise que l'erreur et dans le timer lors de l'utilisation de la fonction incrementer de la classe codevi
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
16 oct. 2004 à 15:35
Première phase, examinons les classes TCompte et TCodevi :
unit Unit2;

interface

uses
  Classes;
//Déclaration du Type compte
type
  Tcompte =  class
  private
    solde: double;
    Num_cpte: integer;
    nom: string;
  public
    //le contructeur sera surchargé par les descendants.
    //nous précisons donc la directive "Virtual"
    constructor create(n: integer; x: string);virtual;
    procedure crediter(m: double);
    procedure debiter(m: double);
    function solde_compte(): double;
  end;

  //Déclaration du type codevi
  Tcodevi = class(Tcompte)
  private
    num_cptecv: integer; //est-ce encore utile  ?
    taux: integer;
    soldecv: double;
  public
    //surcharge le constructeur de la classe "mère"
    constructor create(n: integer; x: string);override;
    function incrementer(): double;
  end;

implementation

constructor Tcodevi.create(n: integer; x: string);
begin
  //appel du constructeur hérité de la classe TCompte
  inherited Create(n, x);
  num_cptecv := n;
  soldecv := 50;
  taux := 3;
end;

constructor Tcompte.create(n: integer; x: string);
begin
  //Appel du constructeur de la classe TObject
  inherited Create;
  Num_cpte := n;
  nom := x;
  solde := 0;
end;

procedure Tcompte.crediter(m: double);
begin
  solde := solde + m;
end;

procedure Tcompte.debiter(m: double);
begin
  solde := solde - m;
end;

function Tcompte.solde_compte(): double;
begin
  Result := solde;
end;

function Tcodevi.incrementer(): double;
begin
  soldecv := soldecv + 50;
  soldecv := soldecv * (1 + taux / 100);
  Result := soldecv;
end;

end.

Les corrections font l'objet de remarques.

Passons à l'exploitation de ces classes dans Unit1 :
procedure TForm1.Button1Click(Sender: TObject);
begin
compte:= compte.create (StrtoInt(Num_cpte.Text),Nom.text);
codevi:= codevi.create (Strtoint(Num_cod.Text),Nom.Text);
ShowMessage('Compté crée')
end;

L'erreur est classique chez les débutants.
Ici, tu essaies de créer une instance des classes T Compte et TCodevi mais en appelant le constructeur sur une autre instance !!!
Le code correct est :
procedure TForm1.Button1Click(Sender: TObject);
begin
compte: = TCompte.create (StrtoInt(Num_cpte.Text),Nom.text);
codevi:= TCodevi.create (Strtoint(Num_cod.Text),Nom.Text);
ShowMessage('Compté crée')
end;


D'autre part, j'attire ton attention sur le fait qu'à chaque fois que tu cliques sur Button1, une nouvelle instance sera créée mais...que tu perds les références de l'ancienne. Donc fuite de mémoire puisque tes objets ne possèdent même pas un un propriétaire chargé de les détruire au moment de la fermeture de la fiche (ou de sa propre destruction) et que seul le redémarrage du système permettra de libérer les ressources mémoires réservées.

On voit donc bien ici combien il est important des respecter une convention d'écriture et de bien faire la distinction entre une classe et une instance de cette classe.

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you
0
loic38760 Messages postés 48 Date d'inscription samedi 16 octobre 2004 Statut Membre Dernière intervention 22 juin 2009
16 oct. 2004 à 16:13
merci beaucoup à present je comprends mieux certaines notions mais néanmoins ma fonction incrementer me pose toujours problème, je ne comprends pas bien la différence entre classe et instance de classe en faites. c'est lorsque je l'appelle dans mon timer qu'il trouve une violation d'accés d'adresse dans cette fonction. Désolé de déranger, c'est trés aimable de m'aider.
0
loic38760 Messages postés 48 Date d'inscription samedi 16 octobre 2004 Statut Membre Dernière intervention 22 juin 2009
16 oct. 2004 à 16:37
dsl c'est vrai que j'avais oublié de preciser, à présent ca fonctionne à merveille ! merci beaucoup de m'avoir aider et expliquer !
0
Rejoignez-nous