Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 2013
-
24 oct. 2006 à 16:17
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 2013
-
27 oct. 2006 à 13:44
salut tout le monde, je viens de rencontrer un probleme plutot etrange, voire depitant :$
j'ai essayé de faire un TObjectList.sort avec class function commme fonction de comparaison. lors de l'appel de cet tri, j'ai une erreur de pointeur. Et lorsque je met un point d'arret sur la fonction de comparaison, il me met que l'adresse de Item2 est $4 . Encore plus etrange, la valeur de self correspond a un element de ma liste a trier ! Est ce que quelqu'un aurit une idée du pourquoi du comment?!!!
voici un "a peu pres" de mon code
type
TMaListe = class(TObjectList)
class function compare(item1, item2: pointer): integer;
end;
TMesObjetsDeListe = class
public
cmpChamp: integer;
end;
class function TMaListe.compare(item1, item2: pointer): integer;
begin
//ici : item1 est bien en element de ma liste, item2 est $4, self est un element de ma liste !!!
result := compareValue(TMesObjetsDeListe(item1).cmpChamp, TMesObjetsDeListe(item2).cmpChamp);
end;
Dans une autre unité
procedure UneAutreClasse.UneProcedure;
var
maListe: TMaListe;
begin
//creation et remplissage de la liste
...
maListe.sort(@TMaListe.compare);
...
end;
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 25 oct. 2006 à 14:00
<TECH>
en fait il te met sur la pile (du pc) les parametres et l'adresse de l'objet ainsi que de la methode au lieu de mettre seulement l'adresse la function et les parametres. c'est du a ton erreur de type.
A mon avis, comme t'as une erreur de type, ce qui devrait etre les parametres sont en fait l'adresse de l'object(self) et l'adresse de ta methode ($4).
</TECH>
c'est pour cela qu'il fat declarer ta function EN DEHORS de ta class et cela marchera.
Essaie stp.
(TIPS: note que si tu veux, la function qui est en dehors de la class peut très bien appeler une methode de class de ta list)
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 25 oct. 2006 à 20:16
D'un côté tu écris :
TListSortCompare = function (Item1, Item2: Pointer): Integer;
Et de l'autre, tu déclares une méthode :
TMaListe = class(TObjectList)
class function compare(item1, item2: pointer): integer;
end;
C'est bien pour cela que ça fonctionne quand tu sors la fonction de la classe.
Attention à ne pas confondre une fonction ou une procédure avec une méthode !!!
Donc, quand tu écris également : "donc j'ai fait une fonction qui a le meme prototype", là je dis non, ce n'est pas pareil.
May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 26 oct. 2006 à 09:02
Non Guillemouze, ça n'a rien à voir avec le passage de paramètres.
Pour info, Delphi se charge du mode de passage des paramètres. Les trois premiers paramètres étant passés par les registres (EAX, EDX et ECX) et les autres étant passés sur la pile.
Une méthode est une procédure d'un objet. En résumé :
TMethod = procedure of object ;
C'est le "of object" qui permet de faire la différence.
May Delphi be with you !
<hr color ="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 24 oct. 2006 à 19:53
Les méthodes de classe ne doivent jamais faire référence à des variables ou propriétés d'une classe qu'elles n'ont pas instancié.
La solution consiste à retirer le mot "class" dans le cas présent..
Note aussi que dans ton code ci-dessus, tu crées une relation de forte dépendance entre les classes TMaListe et TMesObjetsDeListe en transtypant Item1 et Item2. D'un point de vue conceptuel, ce n'est jamais souhaitable.
May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 24 oct. 2006 à 23:08
oui mais je sais que Tmaliste contient uniquement des objets de la classe Tmesobjetsdeliste.
en ce qui concerne la fonction de classe, elle ne depend nulement de variables ou proprietes de la classe. je souhaite mettre la fonction dans la classe car c'est une fonction qui est fortement liée a celle ci.
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 25 oct. 2006 à 08:57
salut,
d'abord cela serrait une bonne idée de déclarer des type pointeur:
(c'est plus propre)
type PMesObjetsDeListe = ^TMesObjetsDeListe;
TMaListe.compare(item1, item2: PMesObjetsDeListe ): integer;
ensuite, comment as-tu déclarer .sort?
selon les sympthome, c'est du a un problpme avec ton type function.
si tu fait:
Type TCompareFct = function(item1,item2 : PMesObjetsDeListe ) of object;
function TMaListe.compare(item1, item2: PMesObjetsDeListe ): integer;
(sans le class)
et
sort(fct : TCompareFct )
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 25 oct. 2006 à 11:19
c'est ce que je me suis dit, mais ca marche presque.
le comportement est quand meme etrange. le fait que self et item1 correspondent bien a des valeurs de ma liste est une pure coincidence, ou bien il y aurait peut etre une once de solution qui pointe son nez?
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 25 oct. 2006 à 14:35
oui mais si c'est une methode de classe, donc elle n'a pas d'adresse d'instance ni de champs. donc ca "pourrait" etre possible.
bien sur que si je sors ma fonction, cela marche sans probleme, c'est ce que j'ai fait, mais j'aurai preferé la mettre à l'interieur de ma classe
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 25 oct. 2006 à 23:23
donc c'est vraiment pas possible :s
la difference entre une procedure/fonction et une methode est donc le passage des parametres sur la pile? si j'ai bien compris, quand on appele une fonction, la pile contient
paramX
...
param1
param0
et quand on appele une methode, c'est :
paramX
...
param1
param0
PtrVersLInstanceDeLaClasse(=self)
?
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 26 oct. 2006 à 10:40
ah ok merci.
dans ce cas la est tu en mesure de me donner plus d'infos sur l'impact du "of object"?
et donc comment se fait il que dans ma class function, mes 2 parametres se retrouvent dans self et le 1erParametre.
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 27 oct. 2006 à 09:17
dans system.pas tu trouve:
type
TProc = procedure;
TMethod = record
Code, Data: Pointer;
end;
tu vois bien que la différence entre une procedure et une methde c'est qu'une methode est accompagnée de l'adresse de l'object. c'est pour cela que tu le trouve a la place d'un des parametres. Note que c'est juste le symtome d'une erreur. te creusses pas trop avec ça. l'important c'est que cela marche.
proposition de solution intermetiaire:
TMaClass = class
// met ton code ici:
class function CompareByXxx(Item1,Itemn2 : Pointer) : Integer;
end;
// passe cette function a ton List.sort :
procedure CompareByXxx(Item1,Item2 : Pointer) : INteger;
begin
Result := TMaClass.CompareByXxx(Item1,Item2);
end;