Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TObject als Übergabeparameter (https://www.delphipraxis.net/57856-tobject-als-uebergabeparameter.html)

hanselmansel 27. Nov 2005 17:54


TObject als Übergabeparameter
 
HiHo,

im Info GK 12 wird uns gerade der Gebrauch von Pointern in Verbindung mit grundlegenden Datentypen beigebracht, aber ich fürchte, ich habe irgendwas vermurkst. Ich habe eine Klasse erstellt, die beliebige Objekte nach dem First in, First out-Prinzip verwalten soll.
Delphi-Quellcode:
  TManagedSnake = class(TObject)
  private
    fAnfang, fLaeufer, fEnde :PListenElement;
  public
    Constructor Create;
    Destructor Destroy; override;

    Function PointerAtEnd :Boolean;
    Function EmptyList :Boolean;

    Procedure newElement(Quelle :TObject);
    Function GetActiveElement :TObject;
    Procedure movePointer(Distance :Integer = 1);
    Function GetAndFreeElement :TObject;

    Procedure EraseAll;
  end;
Ein neues Element in der Liste soll per newElement(Quelle :TObject) erstellt werden. Doch irgendwie kracht es hier bei mir. :cry: Aufgerufen wird die Prozedur in folgendem Code-Abschnitt:
Delphi-Quellcode:
Type
  TString = class(TObject)
  public
    Content :String;
  end;

Var
  Test :TManagedSnake;

procedure TForm1.bt_neuClick(Sender: TObject);
var
  anObject :TString;
begin //<--Breakpoint
anObject := TString.Create;
anObject.Content := e_eingabe.Text;
Test.newElement(anObject as TObject);
anObject.Free;
Wenn ich in die aufrufende Prozedur nun einen Breakpoint setze, wird das Objekt "Test" korrekt erstellt; und ich sehe auch, dass es mit Daten gefüllt wird. Sobald der "blaue Balken" allerdings in die Prozedur newElement springt, zeigt mir Delphi nur noch Quelle = () an, wenn ich mit der Maus über der variablen verharre.
Ich fürchte, dass ich irgendwie nur eine Referenz o.ä. übergeben habe, aber ich weiß nun einfach nicht mehr weiter.

Es wäre super, wenn einer von euch die Zeit finden würde, einmal drüber zu gucken.
Danke wie immer schon im Voraus allein für's Lesen der Frage,

MfG,

hanselmansel

sniper_w 27. Nov 2005 17:59

Re: TObject als Übergabeparameter
 
Wie auch immer, folgendes ist totall fehl am Platz.
Delphi-Quellcode:
anObject.Free;
Du übergibst (speicherst) ein Objekt , den du sofort dannach ins Nirvana schickst?!

hanselmansel 27. Nov 2005 18:16

Re: TObject als Übergabeparameter
 
Die Prozedur, an die übergeben wird, sieht so aus:
Delphi-Quellcode:
Procedure TManagedSnake.newElement(Quelle :TObject);
Var
  Element :PListenElement;
Begin
New(Element);
Element^.Content := Quelle;
If EmptyList then
  Begin
  fAnfang := Element;
  fLaeufer := Element;
  fEnde := Element;
  End
Else
  Begin
  fEnde^.Next := Element;
  fEnde := Element;
  End;
Element^.Next := nil;
End;
Hierbei ist ein PListenElement ein Pointer auf ein Record, das ein TObject und einen Pointer auf das nächste Element beinhaltet.
Was mir Kopfschmerzen bereitet ist die Frage, ob ich das gesamte Objekt an die Prozedur übergebe (inkl. String) oder nur einen Pointer auf den Speicherbereich, wo der Ömes drinsteht. In einem Fall könnte ich das übergebene Element löschen, nachdem ein neues in der Liste angelegt wurde, im anderen Fall muss ich den Pointer auf das Objekt in der Liste verwalten. (IMHO)

Das Problem ist, dass der Übergabeparameter gar nichts ist. Ich habe keine Ahnung, was ich mit eben diesem anstellen soll. :stupid:

sniper_w 27. Nov 2005 18:23

Re: TObject als Übergabeparameter
 
Ich stelle hier eine DoubleLinked-List die (bei mir ;) ) funktioniert...:
Delphi-Quellcode:
type
 TListNode = class(TObject)
   private
     FNext:TListNode;
     FPrev:TListNode;
   public
     procedure AfterConstruction();override;
     procedure BeforeDestruction();override;
   published
     property Next:TListNode read FNext;
     property Prev:TListNode read FPrev;
 end;

 TDoubleLinkedList = class(TObject)
   private
     FHead:TListNode;
     FTail:TListNode;
     FSize:Integer;
   protected
   public
     procedure AfterConstruction();override;
     procedure BeforeDestruction();override;
     procedure Append( Node:TObject );
     procedure InsertBefore( Node, Before:TObject );
     procedure Remove( var Node:TObject; AndDelete:Boolean = False );
     function NextNode( Node:TObject ):TObject;
     function PrevNode( Node:TObject ):TObject;
     procedure Clear();
   published
     property Size:integer read FSize;
     property Head:TListNode read FHead;
     property Tail:TListNode read FTail;
 end;

implementation

uses
  SysUtils;

{ TListNode }

procedure TListNode.AfterConstruction();
begin
  inherited;
  FNext := nil;
  FPrev := nil;
end;

procedure TListNode.BeforeDestruction();
begin
  inherited;
end;

{ TDoubleLinkedList }

procedure TDoubleLinkedList.AfterConstruction();
begin
  inherited;
  FHead := nil;
  FTail := nil;
  FSize := 0;
end;

procedure TDoubleLinkedList.Clear();
  var Node:TListNode;
begin
  while FHead <> nil do
  begin
    Node := FHead;
    FHead := FHead.FNext;
    Node.Free;
  end;
end;

procedure TDoubleLinkedList.BeforeDestruction();
begin
  Clear();
end;

procedure TDoubleLinkedList.Append( Node:TObject );
begin
  if FHead = nil then
  begin
    FHead := TListNode(Node);
    FTail := TListNode(Node);
  end else
  begin
    TListNode(Node).FPrev := FTail;
    FTail.FNext := TListNode(Node);
    FTail := TListNode(Node);
  end;
  Inc(FSize);
end;

procedure TDoubleLinkedList.InsertBefore( Node, Before:TObject );
begin
  if FHead = nil then
  begin
    FHead := TListNode(Node);
    FTail := TListNode(Node);
  end else
  begin
    if Before = FHead then
    begin
      TListNode(Node).FNext := FHead;
      FHead.FPrev := TListNode(Node);
      FHead := TListNode(Node);
    end else
    begin
      TListNode(Node).FNext := TListNode(Before);
      TListNode(Node).FPrev := TListNode(Before).FPrev;
      TListNode(Node).FPrev.FNext := TListNode(Node);
      TListNode(Before).FPrev := TListNode(Node);
    end;
  end;
  Inc(FSize);
end;

procedure TDoubleLinkedList.Remove( var Node:TObject; AndDelete:Boolean );
begin
  if Node = nil then
  begin
    Exit;
  end;

  if Node = FHead then
  begin
    FHead := FHead.FNext;
    if FHead = nil then
      FTail := nil
    else
      FHead.FPrev := nil;
  end
  else if Node = FTail then
  begin
    FTail := FTail.FPrev;
    if FTail = nil then
      FHead := nil
    else
      FTail.FNext := nil;
  end else
  begin
    TListNode(Node).FPrev.FNext := TListNode(Node).FNext;
    TListNode(Node).FNext.FPrev := TListNode(Node).FPrev;
  end;
  Dec(FSize);
  TListNode(Node).FNext := nil;
  TListNode(Node).FPrev := nil;
//  if AndDelete then
//  begin
//    TListNode(Node).Free();
//    Node := nil;
//  end;
end;

function TDoubleLinkedList.NextNode( Node:TObject ):TObject;
begin
 if Node = nil then
   Result := nil
 else
   Result := TListNode(Node).FNext;
end;

function TDoubleLinkedList.PrevNode( Node:TObject ):TObject;
begin
 if Node = nil then
   Result := nil
 else
   Result := TListNode(Node).FPrev;
end;

Der_Unwissende 27. Nov 2005 18:32

Re: TObject als Übergabeparameter
 
Hi,

@sniper_w
Sorry, aber hab zwei Anmerkungen, einerseits solltest du Code der Größe anhängen und nicht posten und das andere ist, nach DP Bedingungen wird keine Schularbeit gelöst. Ausserdem glaube ich das hanselmansel sicher was lernen möchte (immerhin könnte das in einer Klausur vorkommen).

@hanselmansel
Du kannst Klassen casten. Das heißt du wandelst eine Klasse in eine andere um. Um etwas zu casten setzt du einfach den Typ vor deine Variable, diese wird eingeklammert oder du benutzt den as Operator

Delphi-Quellcode:
procedure doFoo(Sender : TObject);
var neuerTyp : TWasAuchImmer;
begin
  // prüfen ob Sender vom richtigen Typ ist
  if Sender is TWasAuchImmer then
    begin
      neuerTyp := TWasAuchImmer(Sender);
    end;
end;
Gruß Der Unwissende

sniper_w 27. Nov 2005 18:37

Re: TObject als Übergabeparameter
 
1.
Zitat:

einerseits solltest du Code der Größe anhängen und nicht posten
Man kann es ruhig auf/zuklappen. Diese Funktion ist dafür gedacht.
2. Ich habe ihm keine Aufgabe gelöst.

hanselmansel 27. Nov 2005 18:42

Re: TObject als Übergabeparameter
 
HiHo :!:

erstmal möchte ich dich beruhigen, dass Sniper nicht meine HA anfertigt. Im Unterricht ging es nur darum, eine solche Listenstruktur zu bauen. (Was bei mir auch schon funktioniert hat.) Da ich es aber hasse, in der Unit, in der auch die Methoden des Forms deklariert sind, so umfangreichen Code zu schreiben, habe ich die Liste in eine eigene Klasse ausgelagert.
Hierbei ist dann der Fehler aufgetreten, dass der Wert auf einmal anscheinend futsch war, und das hat mich irritiert.

Nun funktioniert es. Den Wert kann ich während des Programmlaufs zwar nicht sehen, aber nachdem ich einen Fehler in der Ausgabe beseitigt habe, stimmt das Ergebnis! :bouncing4:

Vielen Dank für die Denkanstöße!

hanselmansel


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:29 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