AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Komplexe Datentypen als Rückgabewert einer Funktion
Thema durchsuchen
Ansicht
Themen-Optionen

Komplexe Datentypen als Rückgabewert einer Funktion

Ein Thema von inriz · begonnen am 14. Dez 2005 · letzter Beitrag vom 14. Dez 2005
Antwort Antwort
inriz

Registriert seit: 18. Okt 2005
15 Beiträge
 
#1

Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 11:40
Hallo,

folgendes Sachverhalt wurde mir zugetragen um meinen Code zu verbessern.
Ich habe eine Funktion namens GetTokenList. Diese Funktion nimmt einen String entgegen (separiert durch ':'), splittet diesen
anhand des Separators auf und schreibt alles in ein Objekt vom Typ TStringList.
Diese TStringList wird in der Funktion allokiert und die Referenz dieses Objektes wird zurückgegeben.
Delphi-Quellcode:
function TfmAppPanel.GetTokenList(sCommand, sSeparator : string) : TStringList;
var
  sTmp : string;
  sCurrentToken : string;
  iPos : Integer;
  iRest : Integer;
  TokenList : TStringList;
begin
  Result := nil;
  sTmp := sCommand;
  TokenList := TStringList.Create;

  iPos := Pos(sSeparator, sTmp);
  if iPos > 0 then
  begin
    repeat
      iRest := Length(sTmp) - iPos;
      sCurrentToken := LeftStr(sTmp, iPos - 1); // hier können laufzeitfehler entstehen ...
      TokenList.Add(sCurrentToken);
      sTmp := RightStr(sTmp, iRest);
      iPos := Pos(sSeparator, sTmp);
    until not (iPos > 0);

    if Length(sTmp) > 0 then
    begin
      TokenList.Add(sTmp);
    end;
    Result := TokenList;
  end;
end;
Nun wurde mir gesagt, gib anstatt der Referenz, TokenList.Text zurück. Der String, der sich in TokenList.Text befindet kann einer anderen Liste zugewiesen werden(AList.Text := GetTokenList(...)) und man kann normal mit der Liste (Alist) wie gewohnt weiterarbeiten. Meine Frage ist, macht diese Änderung Sinn, wenn ja? Warum?
Mein Kenntnisstand sagt, Allokation ist mit viel Rechenleistung behaftet und bei der mir zugetragenen Lösung muss ich noch eine weitere TStringList allokieren, was für mich keinen Sinn ergibt, da es ja Pointer gibt. Wie sieht ihr das? Ist die Lösung berechtigt? Gibt es andere Lösungen?

Gruß inriz
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

Re: Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 12:01
Sinnvoll ist es, die Liste vom Aufrufer deiner Funktion bereitstellen zu lassen:
Delphi-Quellcode:
procedure FillTokenList(const sCommand, sSeparator : string; liste:TStrings);
begin
   Assert(Assigned(liste)); // zur Sicherheit
   liste.clear;
   ...
end;
Damit wird die Funktion zu einer Procedure. Du kannst auch TStrings-Objekte übergeben, die kein TStringList sind. z.B.:
FillTokenList('EXEC', ',', Memo1.Lines); Der vorgeschlagene Umweg über "TokenList.Text" ist keinesfalls zu empfehlen.
Andreas
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#3

Re: Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 12:03
Hi,
sorry aber ich muss mal ganz kurz eine andere Frage stellen, warum machst du es eigentlich so umständlich?

Delphi-Quellcode:
function TfmAppPanel.GetTokenList(sCommand, sSeparator : string) : TStringList;
begin
  Result := TStringList.Create;
  Result.Delimiter := Seperator;
  Result.DelimitedText := sCommand;
end;
Das sollte eigentlich genau das gleiche tun und mit Result.DelimitedText bekommst du auch den original Text zurück.

Ansonsten ist es natürlich komplett von dem was man machen möchte abhängig, wie ein StringTokenizer am sinnvollsten aufgebaut werden sollte. Ich persönlich sehe allerdings wenig Sinn darin den String ungetrennt zurück zu geben (wie es ja nach Änderungswunsch sein würde?).

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Benutzerbild von RavenIV
RavenIV

Registriert seit: 12. Jan 2005
Ort: Waldshut-Tiengen
2.875 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 12:09
Zitat von Der_Unwissende:
Delphi-Quellcode:
function TfmAppPanel.GetTokenList(sCommand, sSeparator : string) : TStringList;
begin
  Result := TStringList.Create;
  Result.Delimiter := Seperator;
  Result.DelimitedText := sCommand;
end;
hiermit erzeugst du aber ein Speicherleck, weil die Stringlist nirgends zerstört (Free) wird.
Klaus E.
Linux - das längste Text-Adventure aller Zeiten...
Wer nie Linux mit dem vi konfiguriert hat, der hat am Leben vorbei geklickt.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 12:21
Zitat von RavenIV:
Zitat von Der_Unwissende:
Delphi-Quellcode:
function TfmAppPanel.GetTokenList(sCommand, sSeparator : string) : TStringList;
begin
  Result := TStringList.Create;
  Result.Delimiter := Seperator;
  Result.DelimitedText := sCommand;
end;
hiermit erzeugst du aber ein Speicherleck, weil die Stringlist nirgends zerstört (Free) wird.
Nun ja, die StringList ist Rückgabewert einer Funktion, der jenige der sie empfängt muss sich also darum kümmern, dass sie wieder frei gegeben wird. Das geht aber logisch aus einem solchen Typen als Rückgabewert hervor (gut, ist vielleicht nicht der sauberste/schönste Weg). Aber würde ich sie schon freigeben wäre die Funktion sinnfrei.

Kannst du natürlich auch als procedure machen und dann halt

Delphi-Quellcode:
procedure TfmAppPanel.GetTokenList(sCommand, sSeparator : string; result : TStringList) ;
begin
  Result.clear;
  Result.Delimiter := Seperator;
  Result.DelimitedText := sCommand;
end;
Sorry für den wie immer unkreativen Namen des Parameters, hatte nur keine Lust den Quellcode zu weit zu ändern (zwei weitere Umbenennungen sind viel )

Gruß
  Mit Zitat antworten Zitat
inriz

Registriert seit: 18. Okt 2005
15 Beiträge
 
#6

Re: Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 12:56
Delphi-Quellcode:
sCommand := edtCommand.Text;
if not Length(sCommand) > 0 then
  exit;
AStringList := TStringList.Create;
if not Assigned(AStringList) then
  exit;

AStringList.Delimiter := ':';
AStringList.Text := sCommand;

lblShowListElement.Caption := AStringList[0];
lblDelimitedText.Caption := AStringList.DelimitedText;
lblDelimiter.Caption := AStringList.Delimiter;

AStringList.Free;
Diese Lösung habe ich jetzt implementiert und getestet, führt aber nicht zu dem gewünschtem Ergebnis.
Soweit ich die in der Hilfe angebotene Beschreibeung zu TStringList verstanden habe,
beschreibt Delimiter ein Zeichen, welches genutzt wird, um Text, der aus zusammen gesetzten TStrings besteht, mit Hilfe dieses Delimiters zu "einem" String zu formen.

Meine Aussage bzw. der Tatbestand meiner Ausführungen im obigen Beitrag scheinen mit diesem Beitrag widersprüchlich zu sein,
da dort der Text "einer" StringListe, dem Text einer "anderen" StringListe zugewiesen wird und das Arbeiten
mit dieser "anderen" StringListe einwandfrei funktioniert, sprich Zugriffe dieser Art AStringList[0] auch funktionieren.

Gruß inriz
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#7

Re: Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 13:07
Zitat von inriz:
Ich habe eine Funktion namens GetTokenList. Diese Funktion nimmt einen String entgegen (separiert durch ':'), splittet diesen
anhand des Separators auf und schreibt alles in ein Objekt vom Typ TStringList.
Diese TStringList wird in der Funktion allokiert und die Referenz dieses Objektes wird zurückgegeben.
Genau das würde
Delphi-Quellcode:
function TfmAppPanel.GetTokenList(sCommand, sSeparator : string) : TStringList;
begin
  Result := TStringList.Create;
  Result.Delimiter := Seperator;
  Result.DelimitedText := sCommand;
end;
machen.
Beispiel :

Delphi-Quellcode:
var s : String;
    tokenList : TStringList;
begin
  s := 'a:b:c:Irgendetwas:...';
  tokenList := GetTokenList(s, ':');
  // tokenList.Count = 5,
  // tokenList.Strings[0] = 'a'
  // tokenList.Strings[1] = 'b'
  // tokenList.Strings[2] = 'c'
  // tokenList.Strings[3] = 'Irgendetwas'
  // tokenList.Strings[4] = '...'
end;
Oder hab ich dich falsch verstanden? Werde mir mal gleich deinen Code anschauen, moment

Ja, ist genau das was deine Funktion auch macht nur schon gekapselt. By the way, eine TStringList arbeitet auf den DelimitedText wie ein StringTokenizer (wenn ein Delimitter vorhanden ist), nich auf Text. Wenn du also wie gepostet vorgehst, stehen in der StringList wie bei deinem Ergebnis die einzelnen Token drin

[Edit]Code angesehen und letzten Absatz eingefügt[/Edit]
  Mit Zitat antworten Zitat
inriz

Registriert seit: 18. Okt 2005
15 Beiträge
 
#8

Re: Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 13:25
Richtig:
Delphi-Quellcode:
AStringList.Delimiter := ':';
AStringList.DelimitedText:= sCommand;
Falsch:
Delphi-Quellcode:
AStringList.Delimiter := ':';
AStringList.Text:= sCommand;
War ein übersehener Fehler meinerseits. Danke für die Hilfe.

Gruß inriz
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#9

Re: Komplexe Datentypen als Rückgabewert einer Funktion

  Alt 14. Dez 2005, 13:35
Hauptsache läuft

Der Unwissende
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:56 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