Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Klasse als parameter übergeben Const, Var, ... (https://www.delphipraxis.net/212392-klasse-als-parameter-uebergeben-const-var.html)

norwegen60 3. Feb 2023 10:36

Klasse als parameter übergeben Const, Var, ...
 
Hallo zusammen,

bisher wurde in einer Anwednung, die ich betreue folgendes verwendet
Delphi-Quellcode:
function LoadFromDB(iID:Integer):TMyClass;
begin
  Result := TMyClass.Create;
  ...
  Result.ID = dbQuery.FieldByName('ID').AsInteger;
  ...
end;

function GetMyClass(iID:Integer):TMyClass
begin
  Result := nil;
  for i:= 0 to MyClassList.Count-1 do
  begin
    if MyClassList[i].ID = iID then
    begin
      Result := MyClassList[i];
      break;
    end;
  end;

  if Result = nil then
  begin
    Result := LoadFromDB(iId);
    if Result <> nil then
      MyClassList.Add(Result);
  end;
end;
Das heißt die Klasse wurde in der Function erstellt und als Result zurück gegeben. Das funktioniert so weit auch fehlerfrei auch wenn es unschön ist, dass die Klasse "fremderzeugt" wird.

Ich möchte jetzt aber z.B. ein Refresh einbauen und muss damit der LoadFromDB sagen, dass die Klasse schon existiert und diese auch übergeben.
Mein Konstrukt sähe also eher so aus

Delphi-Quellcode:
function LoadFromDB(aMyClasse:TMyClass; iID:Integer):Boolean; // oder besser LoadFromDB(var/const aMyClasse:TMyClass; iID:Integer) ????????
begin
  ... SQL um Datensatz zu finden
  Result := not sql.IsEmpty;
  ...
  aMyClasse.ID = dbQuery.FieldByName('ID').AsInteger;
  ...
end;

function GetMyClass(iID:Integer; bRefresh:Boolean):TMyClass
begin
  Result := nil;
  for i:= 0 to MyClassList.Count-1 do
  begin
    if MyClassList[i].ID = iID then
    begin
      Result := MyClassList[i];
      break;
    end;
  end;

  if (Result = nil) or bRefresh then
  begin
    bNew := False;
    if Result := nil then
    begin
      Result := TMyClass.Create;
      bNew := True;
    end;

    if not LoadFromDB(Result, iId) then // Wenn nichts gefunden wieder Free
      FreeAndNil(Result);

    if bNew and (Result <> nil) then
      MyClassList.Add(Result);
  end;
end;
Zwei Fragen:
  • Gibt es ein grundsätzliches Strukturproblem bei dem neuen Aufbau
  • Wie unterscheidet sich bei einer Klasse ob ich die Klasse als Var, Const oder ohne Zusatz in der Parameterliste übergebe

Ich habe mal irgendwo gefunden, wie sich das unterscheidet, finde es aber leider nicht mehr. Bei Variablen ist es klar, aber bei dem Pointer??
Ich meine es war so was wie
  • Var MyClass könnte auch in LoadFromDB erstellt werden wenn NIL rein gegeben wird
  • Const MyClass muss schon erstellt sein
  • und ohne Zusatz?
Grüße
Gerd

KodeZwerg 3. Feb 2023 11:10

AW: Klasse als parameter übergeben Const, Var, ...
 
Zitat:

Zitat von norwegen60 (Beitrag 1518259)
Wie unterscheidet sich bei einer Klasse ob ich die Klasse als Var, Const oder ohne Zusatz in der Parameterliste übergebe

Delphi-Quellcode:
procedure foo(bar)
bar wird als wert übergeben

Delphi-Quellcode:
procedure foo(var bar)
bar wird als referenz übergeben

Ich hoffe es hilft.

KodeZwerg 3. Feb 2023 11:17

AW: Klasse als parameter übergeben Const, Var, ...
 
Hier ist die vermisste Erklärung zu denParametern :thumb:

DeddyH 3. Feb 2023 11:18

AW: Klasse als parameter übergeben Const, Var, ...
 
Solange man nicht versucht, innerhalb der Routine die übergebene Instanz zu ändern, gibt es funktional eigentlich keinen Unterschied. Falls aber doch:
Delphi-Quellcode:
procedure Wuppdi(MyClass: TMyClass);
begin
  MyClass := TMyClass.Create; // funktioniert, die Originalinstanz bleibt unberührt
end;
Delphi-Quellcode:
procedure Wuppdi(var MyClass: TMyClass);
begin
  MyClass := TMyClass.Create; // funktioniert, die Originalinstanz wird überschrieben
end;
Delphi-Quellcode:
procedure Wuppdi(const MyClass: TMyClass);
begin
  MyClass := TMyClass.Create; // kompiliert nicht, und das ist auch gut so
end;

himitsu 3. Feb 2023 11:20

AW: Klasse als parameter übergeben Const, Var, ...
 
Klassen sind im Prinzip Pointer, also ihr Inhalt kann auch ohne VAR und sogar bei CONST geändert werden.

Eine Art "real const" ist auch nicht möglich, da der Compiler garnicht entscheiden/wissen kann, ob z.B. beim Zugriff auf Property/Methoden sich etwas ändert.

prinzipiell halte ich es so
Code:
VAR obj        = es kann/wird das komplette Objekt durch eine andere Instanz getauscht/erstellt/freigegeben

OUT obj        = es geht nie etwas (gültiges) rein und es kommt immer was Neues raus, oder NIL

obj            = die Instanz bleibt gleich, aber ihr inhalt könnte sich ändern

CONST          = prinzipiell der Inahlt der Klasse ändert sich nicht (auch wenn es eigentlich nichts mit dem CONST zu tun hat, da sich der Zeiger so oder so nicht ändert, also nur als Dokumentation)
                  (ok, Meistens lasse ich es auch in diesem Fall oft weg, also gemischt mit OHNE)

CONST [Ref] obj = Ist wie CONST, aber der Zeiger selbst wird dennoch als Referenz auf die Variable übergeben, nicht nur der Wert des Pointers.
                  Syntaktisch hat es für mich aber keine Beziehung zu Objekten.

Bei der Benamung hab ich dann ich noch ein paar Conventionen (so in etwa):

GetIrgendwas gibt ein Objekt zurück, aber es kümmert sich jemand um die Freigabe (es bleibt in dessen Besitz).
CreateIrgendwas oder GenerateIrgendwas erzeugt etwas und der Aufrufer hat sich um die Freigabe zu kümmern.
Und ansonsten wird Abweichendes brav im
Delphi-Quellcode:
/// <returns> ... </returns>
erwähnt.

norwegen60 3. Feb 2023 11:22

AW: Klasse als parameter übergeben Const, Var, ...
 
[QUOTE=KodeZwerg;1518261]
Zitat:

Zitat von norwegen60 (Beitrag 1518259)
Ich hoffe es hilft.

Nicht wirklich, denn eine Klasse ist ja ein Zeiger und damit die Übergabe immer eine Referenz, die auf denselben Speicherbereich zeigt.

norwegen60 3. Feb 2023 11:23

AW: Klasse als parameter übergeben Const, Var, ...
 
Zitat:

Zitat von himitsu (Beitrag 1518265)
prinzipiell halte ich es so

Super, das passt

Uwe Raabe 3. Feb 2023 11:59

AW: Klasse als parameter übergeben Const, Var, ...
 
Kann es sein, dass du die Instanz beim Refresh noch aus der Liste entfernen musst, wenn LoadFromDB fehlschlägt? Der Datensatz kann ja vielleicht zwischenzeitlich gelöscht worden sein.

Da die Reihenfolge in der Liste offenbar keine Rolle spielt, wäre vielleicht ein
Delphi-Quellcode:
TObjectDictionary<Integer, TMyClass>
für MyClassList die geschicktere Wahl. Dann schrumpft das GetMyClass etwas zusammen:

Delphi-Quellcode:
function GetMyClass(iID: Integer; bRefresh: Boolean): TMyClass;
begin
  if MyClassList.TryGetValue(iID, Result) then begin
    if not LoadFromDB(Result, iID) then
    begin
      MyClassList.Remove(iiD);
      Result := nil;
    end;
  end
  else
  begin
    Result := TMyClass.Create;
    if LoadFromDB(Result, iID) then
      MyClassList.Add(iID, Result)
    else
      FreeAndNil(Result);
  end
end;

Sherlock 3. Feb 2023 12:03

AW: Klasse als parameter übergeben Const, Var, ...
 
Nach meinem beschränkten Verständnis ist eine Klasse nur die Definition aus der man ein Objekt erzeugen könnte. Womit hier also die ganze Zeit hantiert wird sind Objekte. Es werden keine Klassen übergeben oder erzeugt, sondern Objektinstanzen einer Klasse. Damit zeigen Klassen auch auf nichts anderes als ihre eigene Definition. Die Objekte jedoch sind "veraltet" formuliert, Zeiger auf individuelle Datenstrukturen, die durch eine Klasse definiert sind.

Dermaßen mit semantischen Grundlagen bewaffnet wird hoffentlich einiges klarer.

Sherlock
-der fast schon enttäuscht ist, daß keiner auf diesen Umstand aufmerksam gemacht hat

norwegen60 7. Feb 2023 07:50

AW: Klasse als parameter übergeben Const, Var, ...
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1518270)
Kann es sein, dass du die Instanz beim Refresh noch aus der Liste entfernen musst, wenn LoadFromDB fehlschlägt?

Bei mir ist es tatsächlich so, dass Daten nie mehr gelöscht werden. Sie werden höchstens auf Deaktiv gesetzt. Trotzdem Danke für den Hinweis

Zitat:

Zitat von Sherlock (Beitrag 1518271)
Nach meinem beschränkten Verständnis ist eine Klasse nur die Definition aus der man ein Objekt erzeugen könnte.

Entschuldige die semantische Verwirrung. Ich habe da wohl tatsächlich den falschen Begriff verwendet. Aber ich hatte weiter oben ja geschrieben, dass es sich doch nur um ein Zeiger handelt. Ich hatte aber geglaubt mal gelesen zu haben, dass es trotz Zeiger einen Unterschied macht zwischen Parameterübergabe Leer, Var und Const. Es kann aber sein, dass es genau das war, was Himitsu schrieb: Ein "eigener" Hinweis, wie man die Daten behandeln sollte


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:52 Uhr.
Seite 1 von 2  1 2      

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