Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Klatsch und Tratsch (https://www.delphipraxis.net/34-klatsch-und-tratsch/)
-   -   VAR oder nicht VAR Überlegungen (https://www.delphipraxis.net/183273-var-oder-nicht-var-ueberlegungen.html)

Mavarik 26. Dez 2014 13:50

VAR oder nicht VAR Überlegungen
 
Hallo Zusammen.

Unit A definiert:

Delphi-Quellcode:
type
   TFoo = Record
            MeinFeld : String;
          end;
Unit B definiert:

Delphi-Quellcode:
type
   TFoo = Class
    Public
      MeinFeld : String
   end;
Dann gibt es noch Unit C mit

Delphi-Quellcode:
Procedure A(AFoo : TFoo);
begin
  AFoo.MeinFeld := 'Warum kommt das hier nicht zurück';
end;
oder besser?
Delphi-Quellcode:
Procedure A(Var AFoo : TFoo);
begin
  AFoo.MeinFeld := 'Das kommt auf jeden Fall zurück';
end;
OK, Worum geht es mir?

Bei Records macht der Var Parameter einen Unterschied.
- Call bei Referenz
- Call bei Value

Theoretisch bei Classen auch, aber nur für den Objectzeiger.

Wenn ich also nach 5 Jahren mir eine Procedure anschaue kann ich mich ggf. nicht mehr daran erinnern, ob TFoo ein Object oder ein Record ist.

Daher meine These oder nennt es mein DesignPattern.

Wenn an Procedure ein Objekt übergeben wird, schreibe ich immer VAR. So kann ich an der Definition der Procedure sehen, dass wenn ich innerhalb der Procedure etwas mit AFoo mache, es Auswirkungen nach draußen hat.

Bin gespannt auf Eure Kommentare. Besonders ob wenigsten einer Dabei ist mit "Gute Idee"... :stupid:

Mavarik

DeddyH 26. Dez 2014 14:29

AW: VAR oder nicht VAR Überlegungen
 
Tendenziell eher schlecht als gut. Im Normalfall will man ja an der Objektinstanz an sich überhaupt nichts verändern, sondern lediglich mit deren Methoden oder Properties arbeiten, wieso also als Variablenparameter übergeben? Es kann natürlich auch Ausnahmen geben, aber das sind dann meist wirklich Ausnahmen. Wenn die Übergabeart schon dazu dienen soll, auseinanderzuhalten, was ein Record und was eine Klasse ist (wobei mir das schon überdenkenswert erscheint), dann übergib doch Objektinstanzen als Konstantenparameter, da kann dann auch nichts schiefgehen.

Sir Rufo 26. Dez 2014 14:43

AW: VAR oder nicht VAR Überlegungen
 
Zeig doch bitte mal wie Unit A, Unit B und Unit C zusammengesteckt aussehen.

Denn entweder ist
Delphi-Quellcode:
TFoo
in Unit C der
Delphi-Quellcode:
Record
oder die
Delphi-Quellcode:
class
, aber es geht niemals das überraschenderweise mal die Klasse oder der Record in die Prozedur von Unit C läuft.

Das muss man also schon bewusst so programmieren.
Delphi-Quellcode:
unit C;

interface

uses A, B;

procedure A( var Foo : A.TFoo ); overload; // record
procedure A( Foo : B.TFoo ); overload; // class
Und auch wenn da beide gleich benannt sind, handelt es sich intern um grundverschiedene Typen, so als ob der eine Typ
Delphi-Quellcode:
TAnton
und der andere
Delphi-Quellcode:
TFritz
heißen würde.

Das Grundverhalten von
Delphi-Quellcode:
record
und
Delphi-Quellcode:
class
ist nun mal auch grundverschieden, dass man die eben nicht über einen Kamm scheren kann.

Namenloser 26. Dez 2014 14:55

AW: VAR oder nicht VAR Überlegungen
 
Find ich auch eher nicht so gut. Denn wenn ein Objekt als var übergeben wird, dann erlaubt das der aufgerufenen Routine, den Zeiger zu verändern. Also wenn, dann würde ich als „Design Pattern“ eher vorschlagen, Objekte, die verändert werden könn(t)en „normal“ zu übergeben (ohne var und const), und Objekte, die explizit nicht verändert werden dürfen als const (ja ich weiß, dass das const das nicht verhindert, aber zumindest macht es es nicht noch schlimmer im Gegensatz zum var).

Mache ich aber selber nicht so, ich hatte das Problem eigentlich nie.

Der schöne Günther 26. Dez 2014 15:14

AW: VAR oder nicht VAR Überlegungen
 
Am Rande eine dumme Frage- Es macht doch für den Aufrufer keinen Unterschied ob ein Parameter const oder nicht const ist, oder?

Sir Rufo 26. Dez 2014 15:15

AW: VAR oder nicht VAR Überlegungen
 
Man muss sich immer vor Augen halten, was denn da genau übergeben wird, und das ist bei einem Record und einer Klasse eben etwas völlig anderes.

Der Prozeduraufruf arbeitet bei beiden gleich:
Bei
Delphi-Quellcode:
const Value : Type
ist der Wert nicht änderbar, bei
Delphi-Quellcode:
Value : Type
ist der Wert änderbar, geht aber nicht zurück und bei
Delphi-Quellcode:
var Value : Type
ist der Wert änderbar und wird zurückgegeben.

Aber bei einem Record ist der Wert eben der gesamte Inhalt des Records und bei einer Klasse ist der Wert die Referenz auf einen Speicherbereich.

Hier kann es leicht passieren, dass man Birnen und Äpfel verwechselt oder versucht miteinander zu vergleichen.

alda 26. Dez 2014 15:49

AW: VAR oder nicht VAR Überlegungen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1284728)
Am Rande eine dumme Frage- Es macht doch für den Aufrufer keinen Unterschied ob ein Parameter const oder nicht const ist, oder?

Für den aufrufenden nicht, das ist korrekt. Es geht hier eher um eine indirekte Optimierung des Compilers - mit einem "const" vor einem Parameter wird kein "try .. except" um die Verarbeitung des Parameters gebaut.

Aus diesem Grund steht bei mir vor jedem Parameter ein const, es sei denn ich benötige ein var oder ein out.

Mavarik 26. Dez 2014 21:59

AW: VAR oder nicht VAR Überlegungen
 
Zitat:

Zitat von Sir Rufo (Beitrag 1284725)
Zeig doch bitte mal wie Unit A, Unit B und Unit C zusammengesteckt aussehen.

Nee falsch verstanden...

Unit A gehört zu Projekt A von 1990
Unit B gehört zu Projekt B von 2005

Unit C heißt eigentlich Hier_sind_alle_Proceduren_drinn_die_sich_in_den_le tzten_25_Jahren_angesammelt_haben.pas

2015 muss ich einen Fehler suchen und schaue mir eine Procedure an...

Und wen da steht: Procedure GetPLZ2Ort(Var AAdresse:tAdresse);

Bin ich mir sicher, egal ob es ein TObject oder ein Record ist, wenn ich

Adresse.Ort := GetOrt(Adresse.PLZ);
Bla bla bal

Das meine Adresse die ich übergeben habe, sich auch ändert und nicht nur die lokale AAdresse.

Mavarik

p80286 27. Dez 2014 08:50

AW: VAR oder nicht VAR Überlegungen
 
Wenn ich das jetzt richtig verstanden habe, dann hast Du in der Unit B aus einem Record "einfach" mal eine (Krüppel-)Klasse gemacht. Das wird zwar manchmal gerne propagiert, halte ich aber für nicht sooo gelungen, da "Verwechslungsgefahr" besteht.
Hier kehrt sich der "Vorteil", daß Pointer hinter normalen Namen versteckt werden, in einen Nachteil um, denn der Programmierer muß wissen was übergeben wird. Bei solchen Mißverständnissen gefällt mir die "Pointeritis" des Windows-API wieder richtig gut.

Gruß
K-H

Namenloser 27. Dez 2014 12:09

AW: VAR oder nicht VAR Überlegungen
 
Zitat:

Zitat von alda (Beitrag 1284734)
Zitat:

Zitat von Der schöne Günther (Beitrag 1284728)
Am Rande eine dumme Frage- Es macht doch für den Aufrufer keinen Unterschied ob ein Parameter const oder nicht const ist, oder?

Für den aufrufenden nicht, das ist korrekt. Es geht hier eher um eine indirekte Optimierung des Compilers - mit einem "const" vor einem Parameter wird kein "try .. except" um die Verarbeitung des Parameters gebaut.

Aus diesem Grund steht bei mir vor jedem Parameter ein const, es sei denn ich benötige ein var oder ein out.

Wie es sich auf Try-Except aus wirkt, weiß ich nicht, aber ansonsten hast du recht – es ist eine Optimierung. Mit const kann der Compiler beispielsweise die Referenzzählung bei Strings weglassen oder bei Records sich das Umkopieren sparen und stattdessen einfach einen Zeiger übergeben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz