Salut à tous;
J'aimerai savoir si l'équivalent .net "readonly" existe avec Delphi.Je voudrais créer une constante affectable à l'initialization et qu'on ne peut plus modifier par la suite.
Merci.
Salutations.
Version imprimable
Salut à tous;
J'aimerai savoir si l'équivalent .net "readonly" existe avec Delphi.Je voudrais créer une constante affectable à l'initialization et qu'on ne peut plus modifier par la suite.
Merci.
Salutations.
Une constante ne convient pas ?
Salut Nono;
Entre autres j'ai un tableau de ce style
"TabEchec:array [TSide,TPiece,TCasesEchiquier,TCasesEchiquier]of boolean;"
que j'initialise au départ dans une boucle et que j'utilise à de nombreux endroits du code mais qui ne doit surtout plus être modifié.Sachant qu'il y a 7 TPiece et 64 TcasesEchiquier, on peut imaginer que créer une constante de TabEchec serait fastidieux.C'est pas grave je le laisse en var globale et ferais attention.
Peut être dans delphi 2010 , avec le 64bits en natif et biblio parallele :yaisse2: on peut rèver.
Salutations.
Bonsoir,
je n'est peut-être pas bien compris le problème, mais pourquoi ne pas utiliser une classe ? Elle possèderait en private ton array[TSide,TPiece,TCasesEchiquier,TCasesEchiquier]of boolean que tu chargerai par exemple dans le constructeur, puis elle publierait une méthode TabEchec( TSide,TPiece,TCasesEchiquier,TCasesEchiquier):Boolean qui retourne la valeur correspondante de ton array. Ainsi tu n'as à utiliser cet array que dans la classe et comme il est dans la partie private, il n'est de toute façon pas accessible aux autres classes (sauf si elles se trouvent dans la même unité).
@++
Dany
Salut Skywaukers;
C'est pas vraiment un problème, c'était juste pour savoir s'il y avait l'équivalence.Je sais qu'il y a 1000 façons d'empecher l'accés au tableau mais j'essaie d'éviter les appels de fonctions en utilisant au max les constantes,la
vitesse étant la priorité dans mon cas.
Merci d'avoir pris le temps de me répondre.
Salutations.
Avec les propriétés et des méthodes d'accès en lecture marquées inline, le résultat compilé sera équivalent à un accès à un tableau.
En fait il te suffit de déclarer une constante typée :
Ici tb est une constante. Donc à moins de cocher l'option "Constantes typées affectables", la variable correspondante est en lecture seule (la définition d'une constante quoi !).Code:
1
2
3
4
5 type TMonTableau = array[0..3] of integer; const tb : TMonTableau = (0, 1, 2, 3);
Maintenant comment modifier malgré tout cette constante au moment de l'initialisation ?
C'est très simple. Les constantes typées sont des variables comme les autres. Donc on peut les modifier, il suffit de tromper le compilateur pour qu'il ne se rende pas compte qu'on va modifier la constante.
Par exemple, en passant par un pointeur :
De cette façon, lorsqu'on modifie la valeur à travers le pointeur ptr, le compilo ne se rend pas compte qu'on modifie en réalité la variable typée.Code:
1
2
3
4
5
6
7
8
9 var ptr : ^TMonTableau; begin ptr := @tb; // On fait pointer le pointeur sur la constante typée. ptr^[0] := 4; ptr^[1] := 5; ptr^[2] := 6; ptr^[3] := 7;
Bien sûr ça ne marche qu'avec les constantes typées. Les constantes non typées n'ont pas de variables associées, elles sont remplacées par leur valeur au moment de la compilation.
Du temps de Turbo Pascal 4, Borland configurait ses applis avec un programme qui patchait directement les Exe pour modifier la valeur des constantes typées directement dans l'exe...
PS: Tu n'as pas dit qu'elle version de Delphi tu utilises. Parce que si je me souviens biens, avant que les variables initialisées ne soient introduites dans le langage, les constantes typées étaient librement modifiables et ne se comportaient que comme des variables initialisées.
Alors ça c'est vraiment affreux ! En plus rien ne garantit que ça fonctionnera toujours. Il est possible qu'un compilateur ou l'autre place les constantes typées dans une plage mémoire protégée en écriture (comme la mémoire qui contient le code du programme). Dans un cas comme celui-là, l'affectation provoquera une violation d'accès à l'exécution.
Salut Sjrd;
C'est dommage car ça me plaisait bien le contournement de Franck (j'utilise delphi 2007 pour win32), mais ton post est le fruit du bon sens donc je préfère en rester là.Comme tu l'as dis on peut utiliser d'autres méthodes mais j'ai trop la flemme de trifouiller tout le code :marteau:
Salutations.
C'est pas très beau j'en conviens. Mais Delphi a un très fort historique de "les constantes typées sont des variables comme les autres". Il y a beaucoup de projets qui ne compilent pas si tu n'autorises pas l'affectation des constantes typées.
De plus quoi que tu fasses, rien ne te garantie que CodeGear ne fera pas une modif dans le compilateur incompatible avec ton appli : "Tiens maintenant les string seront de l'UTF-16. Quoi, il n'y a plus une appli qui fonctionne ?"
Même dans ce cas, on pourrait encore modifier la mémoire. Il faudrait juste le demander gentillement à Windows... Tu n'as jamais modifié dynamiquement le code d'une autre application ? Tous les Trainer le font.Citation:
Il est possible qu'un compilateur ou l'autre place les constantes typées dans une plage mémoire protégée en écriture (comme la mémoire qui contient le code du programme).
Oui, d'accord, mais c'est de plus en plus crade ;)
Et oui j'ai déjà modifié dynamiquement le code d'une appli (de mon appli, d'ailleurs). J'ai des petites routines magiques mais très utiles dans ScDelphiLanguage.pas à ce sujet. Et Sepi le fait tout le temps :mouarf:
As-tu fait des tests de comparaison, pour la vitesse d'exécution, entre la version où tu utilises une "constante", et la version où tu utilises un tableau dynamique et une méthode d'accès comme le suggère Skywaukers?
Le fait que le tableau soit alloué et accessible en lecture seule est une chose, le temps qu'on perd à accéder à une case en est une deuxième :
même si le tableau est une constante, lorsque tu tapes, dans ton code, un truc du style :
il faut bien que le programme puisse transformer les 4 variables "maCouleur", "maPiece", "maCase1" et "maCase2" en un offset dans le tableau.Code:if TabEchec[maCouleur][maPiece][maCase1][maCase2] then ...
Ce qui veut dire que, dans le code assembleur produit, il doit y avoir, d'une manière ou d'une autre, un bout qui fait cette opération :
Entre le laisser produire par le compilateur et l'écrire toi-même dans une méthode inline, je ne pense pas qu'il y ait énormément de différence de performances.Code:
1
2
3
4
5
6 ... LOffset := maCouleur * _Nb_TPiece_ * _Nb_Cases_ * _Nb_Cases_ + maPiece * _Nb_Cases_ * _Nb_Cases_ + maCase1 * _Nb_Cases_ + maCase2 ; TabEchec[LOffset] ...
Par contre, tu serais plus serein sur l'absence d'accès en écriture du résultat. Et ça, ce n'est pas négligeable, je pense.