![]() |
anfänger: stack als klasse erstellen
hallo,
ich möchte mir zu lernzwecken einen stack als klasse erstellen. habe mir zur oop deshalb auch schon ein tutorial durchgelesen. habe bis jetzt folgendes:
Delphi-Quellcode:
bekomme sofort einen compilerfehler:
type
Tmystack = class procedure create; procedure pop; procedure push(str : string); function firstItem: string; end; [Fehler] Unit1.pas(19): E2065 Ungenügende Forward- oder External-Deklaration: 'Tmystack.create' für jede der proceduren. wäre nett wenn mir einer weiterhelfen könnte gruß nkaaa |
Re: anfänger: stack als klasse
Du mußt die Methoden implementieren (zumindest als stubs).
|
Re: anfänger: stack als klasse
danke, funktioniert :spin2:
|
Re: anfänger: stack als klasse
Create würde ich allerdings als Konstruktor deklarieren, und nicht als normale Prozedur.
Delphi-Quellcode:
constructor Create;
|
Re: anfänger: stack als klasse
Und Pop würde ich als function deklarieren, denn irgendwem musst du ja den Wert zuweisen, den du vom Stack holst ;)
|
Re: anfänger: stack als klasse
dazu war eigentlich
Delphi-Quellcode:
gedacht :wink:
function firstItem: string;
also erst angucken was draufliegt und dann eventuell mit pop runterschmeissen. |
Re: anfänger: stack als klasse
naja... wenn du nix aufm stack hast eben ne exception werfen ^^
ansonsten ist es so, dass "pop" ein anerkanntes "signalwort" ist. bei firstitem würd ich eher vermuten, dass ich da zugreifen kann, ohne dass er was runterschmeißt. |
Re: anfänger: stack als klasse
ich glaub du hast mich falsch verstanden.
die function firstitem liefert das element zurück, was ich zuletzt auf den stack gepackt habe; danach entscheide ich mich dann, ob ich das element wirklich runterschmeissen will (mit pop). pop schmeisst hier wirklich nur das element vom stack, ohne irgendetwas zurückzugeben. Zitat:
|
Re: anfänger: stack als klasse
Zwei Sachen fallen mir auf:
1. Pop ist normalerweise eine Funktion, die das oberste Element löscht und den Inhalt zurückgibt. 2. Die Funktion, die du firstItem nennst, bezeichnet man normalerweise als Peek. Ist eigentlich egal, aber so habe zumindest ich es gelernt. |
Re: anfänger: stack als klasse erstellen
Liste der Anhänge anzeigen (Anzahl: 1)
so hab ein bisschen weitergearbeitet:
Delphi-Quellcode:
anbei noch meine kleine testumgebung.
type
Tzeiger = ^Tinfo; Tinfo = Record info : String; next : Tzeiger; End; Tstack = class(Tobject) constructor create; procedure pop; //Element vom Stack runterschmiessen, OHNE es zurückzuliefern! procedure push(info : String); //Element draufpacken function empty : Boolean; //Ist der Stack leer? function GetFirstItem : String; //Liefert das erste Element vom Stack zurück destructor destroy; private var first : Tzeiger; //Zeiger auf das erste Element im STack end; implementation constructor Tstack.create(); begin inherited; new(stack.first); first:=nil; end; procedure Tstack.pop; var help : Tzeiger; begin if not (first = nil) then begin help:=first; first:=first^.next; dispose(help); end; end; procedure Tstack.push(info : String); var help : Tzeiger; begin new(help); help^.info:=info; help^.next:=nil; if (first=nil) then first^:=help^ else begin help.next:=first; first:=help; end; end; function Tstack.empty : Boolean; begin result:=(First=nil); end; function Tstack.GetFirstItem : String; begin if not (first=nil) then result:=first^.info else result:='Kein Element im Stack'; end; destructor Tstack.destroy; begin inherited; end; procedure TForm1.Button3Click(Sender: TObject); begin stack.create; end; bekomme im testprogramm sofort beim Stack.create eine zugriffsverletzung :/ die Fehlermeldung kommt selbst dann noch, wenn ich das
Delphi-Quellcode:
ausklammere.
new(stack.first);
wer weiß rat? :wink: |
Re: anfänger: stack als klasse erstellen
Delphi-Quellcode:
Du solltest dir die Pascal Naming-Conventions angewöhnen:
type
Tzeiger = ^Tinfo;
Delphi-Quellcode:
PZeiger = ^TInfo;
Delphi-Quellcode:
Eigentlich sollte er hier schon beim var streiken.
var first : Tzeiger; //Zeiger auf das erste Element im STack
Delphi-Quellcode:
FFirst: PInfo;
Delphi-Quellcode:
Erstens greifst du hier auf eine Variable Stack zu, ganz pöse und auch unsinnig. Zweitens weist du FFirst gleich danach nil zu, also spar dir doch das Erstellen.
constructor Tstack.create();
begin inherited; new(stack.first); first:=nil; end; Ergo: Bis jetzt kannst du den Konstruktor einfach weglassen.
Delphi-Quellcode:
else result:='Kein Element im Stack';
![]()
Delphi-Quellcode:
Den Rest kann ich mir leider nicht mehr anschauen, Simpsons rufen ;) .
stack := TStack.Create;
|
Re: anfänger: stack als klasse erstellen
naja gut, die bezeichnung werd ich dann noch ändern.
Delphi-Quellcode:
die variable "first" brauche ich aber in jedem fall, sie zeigt immer auf das erste element im stack.
Tstack = class(Tobject)
... ... private var first : Tzeiger; //Zeiger auf das erste Element im Stack end; wie bzw. wo könnte ich sie denn besser deklarieren?
Delphi-Quellcode:
mit dem constructor habe ich das so verstanden, dass er speicherplatz für ein element reserviert.
constructor Tstack.create();
begin inherited; stack:=stack.create; first:=nil; end; jetzt weiß ich aber auch nicht genau. :| mit
Delphi-Quellcode:
wird ja eigentlich auch schon der speicherplatz für die variable stack reserviert oder?
var stack : Tstack
wozu dann extra das "constructor"? könnte man nicht immer einfach "procedure" nehmen?
Delphi-Quellcode:
: ein neuer stack hat noch kein element, deshalb habe ich "first" auf nil gesetzt.
first:=nil;
|
Re: anfänger: stack als klasse erstellen
Instanzvariablen werden automatisch auf 0 initialisiert. also eine referenz ist automatisch nil.
|
Re: anfänger: stack als klasse erstellen
also so wie es aussieht ist der constructor dann wirklich überflüssig.
bleibt noch die frage wo ich das
Delphi-Quellcode:
innerhalb der klasse deklarieren soll.
var first : Tzeiger; //Zeiger auf das erste Element im Stack
|
Re: anfänger: stack als klasse erstellen
Mach aus dem
Delphi-Quellcode:
mal ein
type
Tzeiger = ^Tinfo;
Delphi-Quellcode:
Dann weiß jeder sofort was gemeint ist: T->Klasse, P: Zeiger (Pointer) ;)
type
PInfo = ^TInfo; Und das first-Element gehört in den private-Teil, allerdings musst du das var davor weglassen. |
Re: anfänger: stack als klasse erstellen
Liste der Anhänge anzeigen (Anzahl: 1)
hab jetzt alles so gemacht
Delphi-Quellcode:
anbei die ganze testumgebung.
type
Pinfo = ^Tinfo; Tinfo = Record info : String; next : Pinfo; End; Tstack = class(Tobject) //constructor create; procedure pop; //Element vom Stack runterschmiessen, OHNE es zurückzuliefern! procedure push(info : String); //Element draufpacken function empty : Boolean; //Ist der Stack leer? function GetFirstItem : String; //Liefert das erste Element vom Stack zurück destructor destroy; private first : Pinfo; //Zeiger auf das erste Element im Stack end; var Form1: TForm1; var st : Tstack; implementation {$R *.dfm} {constructor Tstack.create(); begin inherited; //new(stack.first); //first:=nil; end; ist anscheinend überflüssig } procedure Tstack.pop; var help : Pinfo; begin if not (first = nil) then begin help:=first; first:=first^.next; dispose(help); end; end; procedure Tstack.push(info : String); var help : Pinfo; begin new(help); help^.info:=info; help^.next:=nil; if (first=nil) then first^:=help^ else begin help.next:=first; first:=help; end; end; function Tstack.empty : Boolean; begin result:=(First=nil); end; function Tstack.GetFirstItem : String; begin if not (first=nil) then result:=first^.info else result:='Kein Element im Stack'; end; destructor Tstack.destroy; begin inherited; end; procedure TForm1.createClick(Sender: TObject); begin //st.create; end; procedure TForm1.pushClick(Sender: TObject); begin st.push(edit1.text); end; procedure TForm1.popClick(Sender: TObject); begin st.pop; end; bekomme immernoch einen fehler (zugrissverletzung) beim "pushen" in der zeile:
Delphi-Quellcode:
if (first=nil) then first^:=help^
|
Re: anfänger: stack als klasse erstellen
Delphi-Quellcode:
begin
if (first=nil) then first := help else begin help.next:=first; first:=help; end; end;
Delphi-Quellcode:
procedure TForm1.createClick(Sender: TObject);
begin st := TStack.Create; end; |
Re: anfänger: stack als klasse erstellen
Hallo,
einige Anmerkungen:
|
Re: anfänger: stack als klasse erstellen
Liste der Anhänge anzeigen (Anzahl: 1)
habe das programm soweit verbessert, zumindest kommen jetzt keine abstürze mehr.
allerdings ist wohl irgendwo ein fehler in der push oder pop procedure. ich kann elemente in den stack packen und er zeigt mir auch immer das oberste elemente mit "getfirstitem", aber wenn ich einmal die pop procedure ausführe wird nur noch (meine exception) angezeigt "Keine Elemente im Stack". hab jetzt schon ne ganze zeit lang geguckt, finde den fehler aber nicht :|
Delphi-Quellcode:
type
Pinfo = ^Tinfo; Tinfo = Record info : String; next : Pinfo; End; Tstack = class(Tobject) constructor create; procedure pop; //Element vom Stack runterschmiessen, OHNE es zurückzuliefern! procedure push(info : String); //Element draufpacken function empty : Boolean; //Ist der Stack leer? function GetFirstItem : String; //Liefert das erste Element vom Stack zurück destructor destroy; private first : Pinfo; //Zeiger auf das erste Element im Stack end; var Form1: TForm1; var st : Tstack; implementation {$R *.dfm} constructor Tstack.create; begin inherited; end; procedure Tstack.pop; var help : Pinfo; begin if not empty then begin help:=first; first:=first^.next; dispose(help); end; end; procedure Tstack.push(info : String); var help : Pinfo; begin new(help); help^.info:=info; help^.next:=nil; if not empty then first:=help else begin help.next:=first; first:=help; end; end; function Tstack.empty : Boolean; begin result:=(First=nil); end; function Tstack.GetFirstItem : String; begin if not empty then result:=first^.info else result:='Kein Element im Stack'; end; destructor Tstack.destroy; begin inherited; //fehlt noch: nacheinander alle stackelemente "disposen" end; procedure TForm1.createClick(Sender: TObject); begin st := TStack.Create; end; procedure TForm1.pushClick(Sender: TObject); begin st.push(edit1.text); end; procedure TForm1.popClick(Sender: TObject); begin st.pop; end; procedure TForm1.Oberstes_ItemClick(Sender: TObject); begin showmessage(st.GetFirstItem); end; |
Re: anfänger: stack als klasse erstellen
Der Fehler steckt in der Methode push:
Delphi-Quellcode:
Wenn du dir die Routine nach der Korrektur etwas genauer ansiehst, wirst du sie sicher vereinfachen können...
if empty then first := help // so sollte es aussehen!
Gruß Hawkeye |
Re: anfänger: stack als klasse erstellen
vielen dank euch allen, kaum zu glauben, aber es funktioniert endlich :mrgreen:
Zitat:
Delphi-Quellcode:
meinst du so vereinfachen?
procedure Tstack.push(info : String);
var help : Pinfo; begin new(help); help^.info:=info; if empty then begin help^.next:=nil; first:=help; end else begin help.next:=first; first:=help; end; end; er würde dann einmal die zuweisung help^.next:=nil; sparen, wenn der stack nicht leer ist. |
Re: anfänger: stack als klasse erstellen
Zitat:
Gruesse, Lizzy |
Re: anfänger: stack als klasse erstellen
Delphi-Quellcode:
procedure Tstack.push(info : String);
var help : Pinfo; begin new(help); help^.info:=info; help^.next:=nil; if empty then first:=help else begin help.next:=first; first:=help; end; end;
Delphi-Quellcode:
verdammt.. ich sehe ehrlich keine Möglichkeit, wie ich das verbessern könnte :wall:
procedure Tstack.push(info : String);
var help : Pinfo; begin new(help); help^.info:=info; if empty then begin help^.next:=nil; first:=help; end else begin help.next:=first; first:=help; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz