2009-12-21 7 views
2

Si je définis un enregistrement, je peux définir une instance de cet enregistrement comme enregistrement constant par exemple.Instance de classe constante

Tunit = record 
    _name: string; 
    _scale: real; 
end; 

const metre: Tunit = 
    (_name: 'metre'; 
    _scale: 1.0; 
) 

que je dois faire quelque chose de similaire où Tunit est une classe et le compteur est une instance de la classe, mais est une instance (notamment) dont les champs associés ne peuvent être modifiés par un autre code. Je ne vois pas comment y parvenir. Des idées s'il vous plaît?

+0

Vous pouvez utiliser le bouton 101010 dans l'éditeur pour mettre en forme du texte en tant que code. – itowlson

+0

jamais vu un tel bouton !!? Où est-ce? – user235720

+0

C'est le 5ème bouton de la barre d'outils d'édition. –

Répondre

4

Il y a deux façons de réaliser quelque chose similaire, selon vos besoins:

La première implique initialisant une instance de votre classe, soit dans une procédure (ne pas oublier de Libère l'instance d'initialisation de l'unité dans la finalisation correspondante procédure) ou en utilisant une fonction d'unité de accesseur pour initialiser l'instance du premier accès:

a)

interface 

    var 
    metre : TUnit = NIL; // Can initialise a unit variable 

    : 

    implementation 

    : 

    initialization 
    metre := TUnit.Create(...); 

    finalization 
    FreeAndNIL(metre); 

    end. 

REMARQUE: Si votre clas s est simplement un conteneur de données tel qu'il apparaît à partir de votre question alors vous pourriez envisager d'omettre la finalisation Free'ing - bien que technicall une fuite de mémoire, vous ne ferez rien car la mémoire utilisée par votre instance sera récupérée lorsque votre application le processus se termine. La libération dans la finalisation peut causer des problèmes si un autre code de finalisation dans votre projet accède à l'instance du compteur après qu'elle a été libérée.

Je vous avertis également de ne pas essayer d'utiliser des classes dites "singleton". Ils ajoutent de la complexité et des frais généraux pour un bénéfice nul dans des cas aussi simples que celui-ci.

b)

interface 

    function Metre: TUnit; 

    implementation 

    var 
    _metre : TUnit = NIL; // Can initialise a unit variable 


    function Metre: TUnit; 
    begin 
    if NOT Assigned(_metre) then 
     _metre := TUnit.Create(...); 

    result := _metre; 
    end; 


    finalization 
    FreeAndNIL(metre); 

    end. 

Les mêmes observations w.r.t l'optionalité de mise au point sont applicables dans ce cas également. Notez également que si la performance est une préoccupation importante et que cette fonction d'accesseur est susceptible d'être utilisée, vous pouvez effectuer des étapes supplémentaires pour optimiser cette zone, en utilisant un pointeur de fonction initialisé initialement à une fonction d'usine, qui se remplace par un pointeur vers une fonction d'accès inconditionnel simple lors du premier accès. La deuxième manière d'y parvenir consiste à utiliser des fonctions de classe pour renvoyer des valeurs fixes d'une classe spécialement dérivée, plutôt que d'utiliser des données de membre. Vous n'avez pas besoin d'instancier la classe du tout et vous n'avez pas besoin de vous en préoccuper. Je ne me souviens pas si Delphi 2010 prend désormais en charge les variables de classe ainsi que les fonctions de classe - si c'est le cas, cela peut aussi être une réponse. Mais si vous n'utilisez pas Delphi 2010, la question serait de toute façon inutile.

Il regarderait un peu quelque chose comme:

TMetre = class(TUnit) 
    class function Name: String; override; 
    class function Scale: Double; override; 
end; 

etc

Je me demande cependant ... savez-vous de l'unité Conversions standard et les unités associées de la fonctionnalité de mesure? Je demande seulement parce que le contenu de cette question semble être quelque chose qui est déjà pris en charge par un aspect existant de la RTL Delphi.

+0

Un grand merci pour tout cela - très utile. Les reconversions, oui j'en avais vaguement conscience, mais je dessine une ontologie ici plutôt que de m'intéresser particulièrement aux conversions d'unités en unités elles-mêmes - elles apparaissent simplement comme faisant partie des exigences ontologiques. – user235720

4

essayer propriétés en lecture seule:

interface 
type 
    TUnit = class 
    private 
    _name: string; 
    _scale: real; 
    class function makeunit(aname: string; ascale: real): TUnit; 
    public 
    property name: string read _name; 
    property scale: real read _scale; 
    end; 

function metre: TUnit; 

implementation 

var 
    _metre : TUnit = nil; 

class function TUnit.makeunit(aname: string; ascale: real): Tunit; 
begin 
    Result._name := aname; 
    Result._scale := ascale; 
end; 

function Metre: TUnit; 
begin 
    if not Assigned(_metre) then 
    _metre := TUnit.makeunit('metre', 1.0); 
    result := _metre; 
end; 

finalization 
    FreeAndNIL(_metre); 
+0

merci - cela semble prendre soin des exigences en lecture seule t – user235720

0

Bien qu'il serait techniquement possible de créer des valeurs d'objet constant, ce concept serait incompatible avec les méthodes de libération de la mémoire normale et Delphi/natif ne supporte pas.

Questions connexes