2010-04-10 4 views
2

On m'a dit plus d'une fois que Delphi gère les classes dynamiques mieux que static.Thereby en utilisant les éléments suivants:Delphi gère-t-il réellement mieux les classes dynamiques que les classes statiques?

type Tsomeclass=class(TObject) 
    private procedure proc1; 
    public 
    someint:integer; 
    procedure proc2; 
end; 

var someclass:TSomeclass; 

implementation 

... 

initialization 
    someclass:=TSomeclass.Create; 
finalization 
    someclass.Free; 

plutôt que

type Tsomeclass=class 
    private class procedure proc1; 
    public 
    class var someint:integer; 
    class procedure proc2; 
end; 

90% des classes dans le projet, je travaille Je n'ai besoin que d'une seule instance. Dois-je vraiment utiliser la première méthode pour utiliser ces classes? Est-il mieux optimisé, géré par Delphi? Désolé, je n'ai pas d'arguments pour sauvegarder cette hypothèse, mais je veux l'avis d'un expert.

Merci d'avance!

+2

Vous devriez éviter d'accéder à someint dans votre deuxième exemple car il n'est valide que lorsque cette classe est instanciée auparavant. Peut-être avez-vous oublié de le marquer comme une variable de classe? En outre, exposer un champ de classe au public me semble juste mal. –

+0

Oui j'ai oublié de faire une variable de classe, mais je l'avais en tête.Mais la question ici n'est pas 'est ce OO'.J'ai écrit un exemple de classe et vous avez raison d'exposer le champ, mais pourquoi personne ne répond à la question principale? –

+0

"On m'a dit": ** par qui **? Dans quel contexte ces gens ont-ils prétendu cela? Ont-ils fourni des preuves? –

Répondre

11

Si vous créez une classe qui ne contient que des variables de classe et des méthodes de classe, vous pouvez l'utiliser sans l'instanciation. C'est à dire. Dans votre second exemple vous pouvez utiliser Tsomeclass.proc2 (mais pas Tsomeclass.someint car cette variable n'a pas été marquée avec le préfixe 'class' comme l'a fait remarquer Uwe).

Pour la différence de vitesse (de petite taille), vous pouvez également marquer vos méthodes de classe comme étant «statiques».

type 
    TSomeclass = class 
    class procedure proc2; static; 
    end; 

Il n'y a pas de comparaison "handle better" à mon avis ici. Delphi vous permet de mettre des membres 'normal' et 'class' dans la classe. Ancien, vous ne pouvez utiliser que sur un objet instancié et ce dernier, vous pouvez utiliser n'importe où. Mais ce n'est que deux parties du support OO dans Delphi.

EDIT: Pour répondre à la question sur la vitesse ...

Mettons en place un programme de test:

program Project61; 

{$APPTYPE CONSOLE} 

type 
    TTestClass = class 
    procedure A(a: integer); 
    class procedure B(b: integer); 
    class procedure C(c: integer); static; 
    end; 

procedure TTestClass.A(a: integer); begin end; 
class procedure TTestClass.B(b: integer); begin end; 
class procedure TTestClass.C(c: integer); begin end; 

var 
    tc: TTestClass; 

begin 
    tc := TTestClass.Create; 
    tc.A(42); 
    tc.B(42); 
    tc.C(42); 
    tc.Free; 
    //TTestClass.A(42); // not possible 
    TTestClass.B(42); 
    TTestClass.C(42); 
end. 

Delphi 2010 avec l'optimisation activée compile les appels .A/.B/.C en

Project61.dpr.30: tc := TTestClass.Create; 
004060C5 B201    mov dl,$01 
004060C7 A154594000  mov eax,[$00405954] 
004060CC E847DAFFFF  call TObject.Create 
004060D1 8BD8    mov ebx,eax 
Project61.dpr.31: tc.A(42); 
004060D3 BA2A000000  mov edx,$0000002a 
004060D8 8BC3    mov eax,ebx 
004060DA E899F9FFFF  call TTestClass.A 
Project61.dpr.32: tc.B(42); 
004060DF BA2A000000  mov edx,$0000002a 
004060E4 8B03    mov eax,[ebx] 
004060E6 E891F9FFFF  call TTestClass.B 
Project61.dpr.33: tc.C(42); 
004060EB B82A000000  mov eax,$0000002a 
004060F0 E88BF9FFFF  call TTestClass.C 
Project61.dpr.34: tc.Free; 
004060F5 8BC3    mov eax,ebx 
004060F7 E84CDAFFFF  call TObject.Free 
Project61.dpr.36: TTestClass.B(42); 
004060FC BA2A000000  mov edx,$0000002a 
00406101 A154594000  mov eax,[$00405954] 
00406106 E871F9FFFF  call TTestClass.B 
Project61.dpr.37: TTestClass.C(42); 
0040610B B82A000000  mov eax,$0000002a 
00406110 E86BF9FFFF  call TTestClass.C 

L'objet est d'abord créé et son adresse est stockée dans le registre ebx.

Pour appeler tc.A, le compilateur prépare le paramètre (42 ou 2A) dans edx, l'adresse de l'instance 'tc' dans l'eax et appelle TTestClass.A.

Presque la même chose se produit dans le cas tc.B, sauf que ebx est déréférencé. Dans les cas .A et .B, eax contient la valeur de 'Self' (équivalent à 'this' de C++). Lorsque tc.A est appelé, eax contient l'adresse de l'instance 'tc'. Quand tc.B est appelé, eax contient autre chose (je suppose qu'il pointe vers les informations de type pour TTestClass mais je ne suis pas vraiment sûr de ça). Lorsque le code appelle tc.C, seul eax est préparé car les méthodes 'statiques' ne peuvent pas faire référence au 'Self'.

Une situation similaire se produit dans les cas TTestClass.B/.C sauf que 'Self' est chargé à partir d'un emplacement constant lorsque ?? adresse du type TTestClass typeinfo ?? est stocké. Quoi qu'il en soit, eax contient la même valeur lorsque B est appelé via l'instance (tc.B) ou via la classe (TTestClass.B).

Ainsi, vous pouvez voir que les appels statiques nécessitent moins de 'mov'. C'était l'accélération ineffaçable dont je parlais.

+0

Mais vous avez dit vitesse, je ne comprends pas. Est-ce la première façon (dans ma question) plus rapide que votre chemin (méthode de classe + statique et aucune instance)? –

+0

Voir aussi le deuxième chapitre du Delphi in a Nutshell: http://oreilly.com/catalog/delphi/chapter/ch02.html – gabr

0

Voulez-vous dire une instance ou aucune instance? Avec votre deuxième exemple, vous ne pouvez pas instancier cela.

Je n'ai encore vu personne utiliser des classes statiques dans le code de production. Vous pouvez toujours déclarer des méthodes statiques (classe) dans votre premier exemple.

Utilisez une classe typée régulière, mais déclarez class var, class procedure et class function(). Vous pouvez appeler les méthodes de classe et référencer les variables de classe sans créer d'instance.

Comme ceci:

type 
    TSomeClass = class(TObject) 
    class var 
     somevar: String; 
    class procedure Hello; 
    end; 

Notez que les variables de classe ont été ajoutés quelque part après Delphi 7, mais vous devez certainement être en mesure de faire des méthodes de classe.

+0

Actuellement une instance, mais si elles étaient statiques, aucune. –

+0

Pourquoi le premier exemple? Si je ne l'initie pas, je peux utiliser TsomeClass.proc1 ou TSomeClass.proc2.Pourriez-vous s'il vous plaît répondre à la question principale - quoi de plus efficace, mieux optimisé et mieux manipulé par Delphi? –

+0

@John, oui. Vous pouvez utiliser des méthodes et des variables de classe sans instancier un objet, exactement comme 'TSomeClass.proc1()'. –

Questions connexes