Objet : Variable de class

Signaler
Messages postés
24
Date d'inscription
samedi 24 mars 2001
Statut
Membre
Dernière intervention
18 novembre 2004
-
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
-
Bonjour j'aurais besoin d'aide, je voudrai savoir comment dans un objet créer un attributs commun à toute les instances de ma classe ???

Je sais pas si je suis clair. Genre en java ça serait :
static int i=0;

Et je cherche comment le faire en delphi, devant les méthode si j'ai compris on met class. Mais devant un attribut il veut pas :
class procedure Merde(); C BON
class i:integer; C PAS BON

Please i need help !!!

Raoutas

10 réponses

Messages postés
24
Date d'inscription
samedi 24 mars 2001
Statut
Membre
Dernière intervention
18 novembre 2004

Je m'excuse je viens de trouver, en fait si mon débat que je fait avec moi même intéresse quelqu'un il fallait juste mettre l'attribut juste après la déclaration de la class tout de suite après le mot clé class pas dans public privé ou protected. Je m'excuse de vous avoir déranger et bien sur je me remercie d'avoir trouver la réponse à mon problême.

Raoutas
Messages postés
24
Date d'inscription
samedi 24 mars 2001
Statut
Membre
Dernière intervention
18 novembre 2004

ça donne :
MonObjet = class
monAttribut:integer; //c'est une var de classe
public
...

private
...
end;

Enfin je crois si qq'un peut confirmer quand même ???
Messages postés
4297
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
28
Voilà une discussion intéressante.
Le Pascal Objet (jusqu'à aujourd'hui et jusqu'à preuve du contraire) ne permet pas de créer de variable de classe. Celà n'aurait aucun sens : une classe est assimilée à un concept. Un concept n'est pas fait pour stocker quelque chose. Ce sont les instances de la classe, c'est à dire leur représentation matérialisée en mémoire qui aura la charge de maintenir les valeurs.
Tel que tu as déclaré monAttribut dans ton exemple, tu déclares comme s'il s'agissait d'un simple membre d'une structure de type Record.

Une approche plus orientée objet voudrait que nous utilisions le qualificatif Property :
  TMonObjet = class
  public
    property MonAttribut : integer;
  end;

A celà, plusieurs raisons :
1/- pouvoir définir finement la portée de ce membre de la classe (public, published, protected, private)
2/- en POO, le programme utilisant cette classe n'a pas à connaitre les détails de l'implémentation ni les valeurs potentiellement utilisables. Une classe doit être en mesure de protéger ses membres de toute valeur qui pourraient créer des effets de bord...

Et comme Delphi met à notre disposition (depuis Delphi 4) un outil hyper pratique sous la forme d'un élément de menu contextuel : "Compléter la classe sous le curseur" (raccourci SHIFT+CTRL+C):

  TMonObjet = class
  private
    FMonAttribut: integer;
    procedure SetMonAttribut(const Value: integer);
  public
    property MonAttribut : integer read FMonAttribut write SetMonAttribut;
  end;

N'ayant pas précisé d'accesseur en lecture/écriture pour cette propriété, Delphi présume un accès complet et génère les noms et les squelettes de méthode dans l'unité (non reproduits ici).

Je voudrais rappeler aussi qu'il existe des conventions d'écriture (voir notamment : Delphi coding standards) et qu'il serait bon, dans le cas présent de préfixer le nom de ta classe par la lettre T. Nous avons trop souvent vu de mélanges et d'erreurs à cause d'une confusion entre la classe et l'instance de la classe à cause de celà.

May Delphi be with you
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
5
Je risque peut etre de me faire mal voir par un admin mais je suis pas tout a fait daccord.
Prenons un exemple.
Soit une classe T. il est pratique de pouvoir stocker dans la classe T le nombre d'instances de cette classe, pour affecter un id par exemple.
Certes on pourrai mettre un compteur dans la classe qui instancie l'objet, mais comment faire si la classe est instanciée a partir de plusieurs classes independantes?

De plus, il me semble que les interfaces fonctionnent un peu sur ce principe en delphi.
J'ai pas trop compris leur fonctionnement mais j'ai cru comprendre qu'il fallai implementer un methode AddRef qui correspond à un compteur de references. Mais la, je connai vraiement pas beaucoup.

Merci Delphiprog si tu peu m'apporter de plus amples informations sur ma facon de penser.
Messages postés
4297
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
28
Pas de problème Guillemouze, chacun est libre de s'exprimer et de faire part de ses convictions tant qu'elles ne sont pas religieuses, politiques ou syndicales

Cela dit, tu as écrit : "Soit une classe T. il est pratique de pouvoir stocker dans la classe T le nombre d'instances de cette classe, pour affecter un id par exemple."
A cela je répond qu'un identificateur n'a pas du tout le même  rôle qu'un compteur de références.

En ce qui concerne les interfaces, si elles possèdent un compteur de référence, c'est pour détruire automatiquement un objet quand il n'est plus référencé nulle part. Pour ta connaissance, j'ajoute que tu n'es pas obligé d'implémenter les méthodes AddRef, Release et QueryInterface à partir du moment où ta classe hérite de TInterfacedObject..

Ce que demandait Raoutas, c'était de savoir s'il pouvait déclarer un membre statique comme cela existe dans d'autres langages. Hélas, dans les déclinaisons pour Win 32, Delphi ne permet pas de telles déclarations.
On peut toutefois adopter une solution qui consiste à déclarer une variable, dans la partie implémentation, du type de l'instance sur  laquelle on souhaite pointer.

L'exemple typique est celui du design pattern singleton que tu peux trouver ici sur ce site et proposé par MHI.

En espérant que cela t'aura aidé à y voir plus clair.


Si tu veux voir l'utilisation des interfaces, je te conseille d'aller voir un de mes derniers codes sources et de lire le tuto qui va bien avec : Design pattern Observer avec Delphi
A+

May Delphi be with you !


<hr color="#008000">
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
5
merci de ta reponse.
mais quelque chose me chagrine quand meme. Je connais vaguement le design pattern singleton, mais ce que je voudrais savoir, c si il existe un moyen d'obtenir une valeur affecté a une classe sans passer par une constante globale. Je m'explique. Imaginons que j'ai des classes et par exemple je souhaite leur affecter une chaine qui les decrit (ceci est purement un exemple et pas ce pourquoi j'en ai besoin). Je voudrais donc pouvoir recuperer cette chaine SANS AVOIR BESOIN D'UNE INSTANCE DE CETTE CLASSE. est ce que tu crois que c'est possible?

merci
Messages postés
4297
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
28
Dans ce cas, tu peux utiliser une méthode de classe en respectant une règle de base : une méthode de classe ne doit pas utiliser les valeurs des propriétés comme s'il s'agissait d'une instance de la classe.
Pour déclarer une méthode de classe, il suffit d'ajouter le mot clé class devant le mot clé procedure ou function.
Un exemple ?

type
  TMaClasse =  class
  public
     class function MaFonction: string;
    classfunction MaFonction2: string;
  end;

implementation

const
  Hello  = 'Good morning !';
{ TMaClasse }

classfunction TMaClasse.MaFonction: string;
begin
  Result :=  'Hello world !';
 end ;

classfunction TMaClasse.MaFonction2: string;
begin
  Result : = Hello;
end;

Ces deux fonctions ne font absolument pas appel à une propriété de la classe qui n'a d'existence que lorsqu'il y a eu instanciation.

Pour les utiliser, c'est simple :
ShowMessage(TMaclasse.MaFonction);

Pas besoin d'instancier un objet de la classe TMaClasse.
Pour plus ample information, jette un oeil dans l'oeil en ligne sur "méthodes de classes".

May Delphi be with you !
<hr color="#008000">
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
5
merci pour l'info, ca resout parfaitement mon probleme. Par contre, il n'y a pas de moyen d'avoir une valeur dynamique, c'est a dire que j'affecte une valeur au retour de cette fonction? (comme par exemple pour le pattern singleton, affecter le singleton en retour de la fonction)

merci beaucoup delphiprog
Messages postés
4297
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
28
Ben si, c'est possible. Pourquoi ça ne le serait pas ?
C'est un peu sur ce principe qu'est basé le design pattern factory :

type
  TMaClass =  class
  public
     class  function GetMaClassInstance:TMaClass;
  end;

implementation

{ TMaClass }

class function TMaClass.GetMaClassInstance: TMaClass;
begin
  Result : = TMaclass.Create;
end;

L'exemple ci-dessus n'est pas forcément bien choisi puisque le résultat retourné ne fait rien de plus qu'un appel au constructeur.
Mais le principe est là. A moins que je n'ai pas bien compris le sens de ta question ?

May Delphi be with you !

<HR color=#008000>
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
5
nan je pense pas que tu ai compris le sens.
Pour ton exemple, dans tous les cas, le retour est fixé (un constructeur, une constante, ...). Ce qui m'interesserai, c'est de modifier le retour de la fonction pendant l'execution. Je t'explique mon probleme exactement.

J'ai une classe
TMyException = class(TException)
constructor create;
end;

constructor TMyException.create;
begin
showMessage(TMyAncetre.recuperer.getInfos);
end;

et ma class TMyAncetre
TMyAncetre = class
class function recuperer:TMyAncetre;
function getInfos:String;
function setRecuperable;
end;

TMyAncetre.recuperer:TMyAncetre;
begin
//La je voudrais retourner une instance mémorisée de TMyAncetre,
//qui n'est pas forcement unique, mais qui est memorisée au moment de l'execution.
//Par exemple, je voudrais retourner la derniere instance
//qui a appelé la fonction setRecuperable.
end;

Comme tu vois, a moins que je nai pas bien saisi le truc, je ne peu pas utiliser le singleton vu que j'ai plusieurs instances.
Merci de ton aide