AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Daten in einer Klassenhierachie ablegen

Ein Thema von steewan · begonnen am 27. Okt 2006 · letzter Beitrag vom 2. Nov 2006
Antwort Antwort
Seite 1 von 2  1 2      
steewan

Registriert seit: 27. Nov 2003
20 Beiträge
 
#1

Daten in einer Klassenhierachie ablegen

  Alt 27. Okt 2006, 10:45
Hallo,

ich weiß nicht genau wie ich in Object Pascal an folgendes Problem herangehe. Ich möchte gerne die Struktur eines Autos zum Beispiel in einer Klassenhierachie ablegen. Beispiel:

Auto besteht aus Karosserie, Reifen, Türen, etc. Die Klasse TAuto soll also eine Liste enthalten, welche dann die anderen Objekte TKarosserie, TReifen, TTÜren enthält. Es kann jetzt natürlich vorkommen, dass ein Auto vier oder fünf Türen hat, bzw. die Türen auch wieder aus einer Struktur besteht. Es sollte also ein Objekt in TAuto geben, wo man andere hinterlegen kann:

TAuto
|
|- Objekte : Tweissnichwas

Jetzt soll TAuto.Objekte[1] := Karosserie; TAuto.Objekte[2] := Türen;. In Türen soll dann natürlich auch jede einzelene Tür hinterlegt sein. Also müsste TTüren ebenfalls eine Objektliste enthalten, welche dann immer ein Objekt TTür enthält mit den entsprechenden Eigenschaften. TAuto.Objekte[2] as TTüren.Obejekte[1] := Tür bzw. TTüren.Obejekte[2] := Heckklappe.

Wie bilde ich so etwas in Delphi ab, wie füge ich neue Objekte ein, wie kann ich auf Eigenschaften zugreifen, etc. Gibt es hierzu vielleicht ein gutes Beispiel oder eine Erklärung ??

Besten Dank
Stefan Blankenagel
  Mit Zitat antworten Zitat
Jürgen Thomas

Registriert seit: 13. Jul 2006
Ort: Berlin
750 Beiträge
 
#2

Re: Daten in einer Klassenhierachie ablegen

  Alt 27. Okt 2006, 11:03
Hallo,
jedes Formular macht das:
  • Form1 ist von einer Klasse TForm abgeleitet und enthält:
  • Edit1 ist von einer Klasse TEdit abgeleitet mit speziellen Eigenschaften
  • Button1 ist von einer Klasse TButton abgeleitet mit speziellen Eigenschaften usw.
Unter NET könntest Du das Verfahren in InitializeComponents() prüfen, wo es für jedes Control einen Create-Befehl gibt und genaue Zuordnungen der Eigenschaften.

Unter Win32 wird es nicht so offensichtlich, aber implizit machen die Verknüpfungen in der Dfm-Datei nichts anderes.

Schau Dir dies einmal genauer an und übertrage es auf Dein Problem. Vielleicht kommst Du damit weiter.

Gruß Jürgen
#D mit C# für NET, dazu Firebird
früher: Delphi 5 Pro, Delphi 2005 Pro mit C# (also NET 1.1)
Bitte nicht sauer sein, wenn ich mich bei Delphi-Schreibweisen verhaue; ich bin inzwischen an C# gewöhnt.
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#3

Re: Daten in einer Klassenhierachie ablegen

  Alt 27. Okt 2006, 13:37
Also ich hätte erstmal einen Autotyp gemacht:
Delphi-Quellcode:
type
  TCar = record
    doors : array of TDoor;
    tires : array of TTire;
  end;
Dann den Türentyp und Reifentyp:

Delphi-Quellcode:
type
  TDoor = record
    width, height : Extended;
    ...
  end;

type
  TTire = record
    radius : Extended;
    tireType : Byte;
    ...
  end;
Du könntest auch statt den Records, Klassen nehmen. Die können dann auch Methoden enthalten und müssen erzeugt/zerstört werden.
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
steewan

Registriert seit: 27. Nov 2003
20 Beiträge
 
#4

Re: Daten in einer Klassenhierachie ablegen

  Alt 27. Okt 2006, 15:38
Hallo,

ja ich hatte es eigentlich mit Klassen vor, da ich dann wirklich dort Methoden einbauen kann. Werde mich noch einmal in diese Richtung damit beschäftigen.

Mit freundlichen Grüßen


Stefan Blankenagel
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#5

Re: Daten in einer Klassenhierachie ablegen

  Alt 27. Okt 2006, 16:46
Zitat von xZise:
Also ich hätte erstmal einen Autotyp gemacht:
Ja, da ist OOP gefordert, aber in Deinem Beispiel macht das keinen Sinn, weil es eben kein OOP ist !

So würde es schon anders aussehen :

Delphi-Quellcode:
type
  TCar = class
    Breite, Höhe, Länge : real;
    AnzahlTueren,
    AnzahlFenster : integer;
  end;

  TPkw = class (TCar)
    Schiebedach : boolean;
  end;
Der Pkw hat dadurch schon direkt eingebaute Türen, Fenster usw. Das TCar hat die noch nicht. Beispiele in dieser Richtung finden sich auch zu Dutzenden im Internet. Man muß sie eben mal lesen und umsetzen.

Edit : Delphi-Tag falsch gesetzt und gleich der nächste Tip : Methoden lassen sich da auch gut einbauen. Trotzdem würde ich zunächst mal die Datenstrukturen richtig aufbauen.
Gruß
Hansa
  Mit Zitat antworten Zitat
steewan

Registriert seit: 27. Nov 2003
20 Beiträge
 
#6

Re: Daten in einer Klassenhierachie ablegen

  Alt 28. Okt 2006, 09:55
Für die Programmentwicklung ist eine genaue Planung der Datenstruktur sehr wichtig. Deshalb mac h ich mir ja die Gedanken.

Ich habe mir jetzt folgende Datenstruktur gebastelt:

Delphi-Quellcode:
    TLeuchte = class
     private
       FZielort : string;
       FAdresse : integer;
     public
       constructor create;
       destructor Destroy; override;
       property Zielort : string read FZielort write FZielort;
       property Adresse : integer read FAdresse write FAdresse;
     end;

     TStromkreis = class
     private
       FAdresse : integer;
       FLeuchten : Array of TLeuchte;

       function GetLeuchte(index:integer):TLeuchte;
     public
       constructor create;
       destructor destroy; override;

       property Leuchte[index:integer]:TLeuchte read GetLeuchte; default;

       property Adresse : integer read FAdresse write FAdresse;
       function get_Anzahl_Leuchten : integer;

       procedure Add_Leuchte(vAdresse : integer; vZielort: string);
       procedure clear_Leuchten;
     end;

     TEinschub = class
     private
       FStromkreise : Array of TStromkreis;
       FAdresse : integer;
       FTyp : integer;

       function GetStromkreis(index:integer):TStromkreis;
     public
       constructor create;
       destructor destroy; override;

       property typ : integer read FTyp write FTyp;
       property Stromkreis[index:integer]:TStromkreis read GetStromkreis; default;
       property Adresse : integer read FAdresse write FAdresse;

       function get_Anzahl_Stromkreise : integer;

       procedure Add_Stromkreis(vAdresse:integer);
     end;

     TGeraet = class
     private
       FZielort : string;
       FAdresse : integer;
       FTyp : integer;
       FEinschuebe : Array of TEinschub;

       function getEinschub(index:integer):TEinschub;
     public

       constructor create;
       destructor destroy; override;

       property Einschub[index:integer]: TEinschub read getEinschub; default;
       property Zielort : string read FZielort write FZielort;
       property Typ : integer read FTyp write FTyp;
       property Adresse : integer read FAdresse write FAdresse;

       function get_Anzahl_Einschuebe : integer;

       procedure Add_Einschub(vTyp : integer; vAdresse: integer);
     end;
Die Prozedur zum einfügen von Daten sind diese:

Delphi-Quellcode:
procedure TGeraet.Add_Einschub(vTyp : integer; vAdresse : integer);
var idx : integer;
    vEinschub : TEinschub;
begin
  idx := get_Anzahl_Einschuebe;
  SetLength(FEinschuebe, idx + 1);

  vEinschub := TEinschub.create;
  FEinschuebe[idx] := vEinschub;
  vEinschub.Free;

  FEinschuebe[idx].Typ := vTyp;
  FEinschuebe[idx].Adresse := vAdresse;
end;

procedure TEinschub.Add_Stromkreis(vAdresse : integer);
var idx : integer;
    vStromkreis : TStromkreis;
begin
  idx := get_Anzahl_Stromkreise;
  SetLength(FStromkreise, idx + 1);

  vStromkreis := TStromkreis.create;
  FStromkreise[idx] := vStromkreis;

  FStromkreise[idx].Adresse := vAdresse;
  vStromkreis.Free;
end;

procedure TStromkreis.Add_Leuchte(vAdresse : integer; vZielort: string);
var idx : integer;
    vLeuchte : TLeuchte;
begin
  idx := get_Anzahl_Leuchten;
  SetLength(FLeuchten, idx + 1);

  vLeuchte := TLeuchte.create;
  FLeuchten[idx] := vLeuchte;
  vLeuchte.Free;

  FLeuchten[idx].Adresse := vAdresse;
  FLeuchten[idx].Zielort := vZielort;
end;
Wenn nun die Struktur mit Daten gefüllt werden sollen, kommt eine Zugriffsverletzung:

Delphi-Quellcode:
  FGeraet := TGeraet.Create;
  FGeraet.Add_Einschub(JSUSV23, 1);
  FGeraet.Einschub[0].Add_Stromkreis(1);
  FGeraet.Einschub[0].Add_Stromkreis(2);
  FGeraet.Einschub[0].Stromkreis[0].Add_Leuchte(1, 'Toilette Herren'); //Hier kommt eine Zugriffsverletzung
  FGeraet.Einschub[0].Stromkreis[0].Add_Leuchte(2, 'Toilette Damen');
  FGeraet.Einschub[0].Stromkreis[0].Add_Leuchte(3, 'Eingang');
  FGeraet.Einschub[0].Stromkreis[0].Add_Leuchte(4, 'Ausgang');
  FGeraet.Einschub[0].Stromkreis[0].Add_Leuchte(5, 'Irgendein Text');
  FGeraet.Einschub[0].Stromkreis[1].Add_Leuchte(6, 'Eine 6. Leuchte');
  FGeraet.Einschub[0].Stromkreis[1].Add_Leuchte(5, 'Toilette Herren');
  FGeraet.Einschub[0].Stromkreis[1].Add_Leuchte(4, 'Toilette Damen');
  FGeraet.Einschub[0].Stromkreis[1].Add_Leuchte(3, 'Eingang');
  FGeraet.Einschub[0].Stromkreis[1].Add_Leuchte(2, 'Ausgang');
  FGeraet.Einschub[0].Stromkreis[1].Add_Leuchte(1, 'Irgendein Text');
Ich dachte erst, es liegt daran, dass ich schon zwei Stromkreise eingefügt habe und jetzt eine Leuchte in Stromkreis 1 einfüge, wodurch aber Speicherplatz im Bereich zwischen Stromkreis 1 und Stromkreis 2 reserviert werden muss. Auch nach Auskommentierung von Add_Stromkreis(2) erscheint in der folgenden Zeile die Zugriffsverletzung.

Gruß
Stefan Blankenagel
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#7

Re: Daten in einer Klassenhierachie ablegen

  Alt 28. Okt 2006, 11:42
Zitat von steewan:
Delphi-Quellcode:
procedure TGeraet.Add_Einschub(vTyp : integer; vAdresse : integer);
var idx : integer;
    vEinschub : TEinschub;
begin
  idx := get_Anzahl_Einschuebe;
  SetLength(FEinschuebe, idx + 1);

  vEinschub := TEinschub.create;
  FEinschuebe[idx] := vEinschub;
  vEinschub.Free;

  FEinschuebe[idx].Typ := vTyp;
  FEinschuebe[idx].Adresse := vAdresse;
end;

procedure TEinschub.Add_Stromkreis(vAdresse : integer);
var idx : integer;
    vStromkreis : TStromkreis;
begin
  idx := get_Anzahl_Stromkreise;
  SetLength(FStromkreise, idx + 1);

  vStromkreis := TStromkreis.create;
  FStromkreise[idx] := vStromkreis;

  FStromkreise[idx].Adresse := vAdresse;
  vStromkreis.Free;
end;

procedure TStromkreis.Add_Leuchte(vAdresse : integer; vZielort: string);
var idx : integer;
    vLeuchte : TLeuchte;
begin
  idx := get_Anzahl_Leuchten;
  SetLength(FLeuchten, idx + 1);

  vLeuchte := TLeuchte.create;
  FLeuchten[idx] := vLeuchte;
  vLeuchte.Free;

  FLeuchten[idx].Adresse := vAdresse;
  FLeuchten[idx].Zielort := vZielort;
end;
Dast geht auch anders:

Delphi-Quellcode:
{ * Variante 1 = Direkte Instanzierung + with * }

procedure TGeraet.Add_Einschub(vTyp : integer; vAdresse : integer);
var idx : integer;
begin
  idx := get_Anzahl_Einschuebe;
  SetLength(FEinschuebe, idx + 1);

  with FEinschuebe[idx] := TEinschub.create do begin
    Typ := vTyp;
    Adresse := vAdresse;
  end;
end;

{ * Variante 2 = direkte Instanzierung * }

procedure TEinschub.Add_Stromkreis(vAdresse : integer);
var idx : integer;
begin
  idx := get_Anzahl_Stromkreise;
  SetLength(FStromkreise, idx + 1);

  FStromkreise[idx] := TStromkreis.create;
  FStromkreise[idx].Adresse := vAdresse;
end;

{ * Variante 3 = direkte Instanzierung + Verzicht, auf eigene Methoden * }

procedure TStromkreis.Add_Leuchte(vAdresse : integer; vZielort: string);
begin
  SetLength(FLeuchten, Length(FLeuchten) + 1);

  FLeuchten[High(FLeuchten)] := TLeuchte.create;
  FLeuchten[High(FLeuchten)].Adresse := vAdresse;
  FLeuchten[High(FLeuchten)].Zielort := vZielort;

// Ich bin mir nicht sicher, ob es hier mit with effektiver ist, da nur einmal die "High()" - Methode aufgerufen werden muss (siehe Variante 1)
end;
Zu deinem Problem: Debug mal in "Add_Leuchte" und sag uns, wo dort der Fehler auftritt... Vielleicht ist "get_Anzahl_Leuchten" "defekt"
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#8

Re: Daten in einer Klassenhierachie ablegen

  Alt 28. Okt 2006, 14:44
Ist der Titel des Themas eventuell gar nicht mehr gültig ? Ich sehe jedenfalls nur eine Aneinanderreihung verschiedener Typen, die nichts miteinander zu tun haben. Da ist nichts zu sehen in Richtung "Klassenhierarchie". Deshalb ist das verwendete override in den Deklarationen auch überflüssig. Glaube zwar nicht, daß das einen bemerkbaren Fehler verursacht, aber es ist trotzdem einer. Dann noch als Beispiel das FAdresse. Wieso wird das überall neu deklariert ? Warum nicht tatsächlich eine Hierarchie, die damit beginnt alles gemeinsame erst mal in eine Basisklasse zu packen und die dann zu vererben. Dabei wird bei den Nachfolgern nur noch das neu deklariert, was auch tatsächlich hinzu kommt. Das gilt nicht nur für Daten, sondern auch für eventuell notwendige neue Methoden.

Ich gehe jetzt mal von dem Auto weg. Geometrische Figuren eignen sich besser. Fangen wir beim Punkt an. Was braucht der ? Eigentlich nur Koordinaten. Na gut er kriegt noch eine Farbe :

Delphi-Quellcode:
TPunkt = class
  x,y : integer;
  Farbe : TColor;
end;
Dann kommt der Kreis. Der hat auch einen Mittelpunkt und eine Farbe. Es kommt hinzu : ein Radius und ich muß ihn zeichnen, also eine durch dem Mittelpunkt und den Radius bestimmte Fläche ausfüllen. Der Punkt hat aber bereits einiges, was man für den Kreis braucht und der sieht deshalb so aus :

Delphi-Quellcode:
TKreis = class (TPunkt)
  Radius : integer;
  protected
     procedure Zeichnen; virtual;
end;
Mehr braucht man nicht, das was in der Deklaration nicht zu sehen ist, das liefert schon der Punkt. Jetzt gehen mir langsam die Ideen aus. Ellipse ist mir zu schwer. Aber wie wäre es noch mit einem berechneten Kreis ? Der soll genauso angezeigt werden, hat auch einen Mittelpunkt und einen Radius. Zusätzlich will ich aber die Fläche und den Umfang wissen:

Delphi-Quellcode:
TBerechneterKreis = class (TKreis)
  Flaeche,
  Umfang : real;
  protected
    procedure BerechneFlaeche; virtual;
    procedure BerechneUmfang; virtual;
end;
Der Rest steckt bereits im Kreis (procedure Zeichnen) oder sogar schon im Punkt (x,y,Farbe). Es kommt eben noch was hinzu. Dann noch ein Quadrat und es stellt sich die Frage, wo man da ansetzen soll. Es hat keinen Radius, sondern sagen wir eine Kantenlaenge. Anders gezeichnet werden muß es auch. Wegen des erwähnten "override" benutze ich aber den Kreis und ignoriere den Radius :

Delphi-Quellcode:
TQuadrat = class (TKreis)
  KantenLaenge : integer;
  protected
     procedure Zeichnen; override;
end;
Da ich vom Kreis her komme, brauche ich ja eine komplett andere Zeichenmethode. Deshalb wird die hier neu deklariert und per override wird die alte vollkommen ignoriert. Bräuchte ich tatsächlich solche Figuren, würde ich wohl nach dem TPunkt eine Weggabelung in der Hierarchie machen. Kreise, Ellipsen usw. und das andere wäre Quadrat, Rechteck, wie heißt noch das schiefe Quadrat ? Da kämen dann auch Winkel ins Spiel usw. So, hoffe mal, daß das hier nicht nur was für Sakura ist.
Gruß
Hansa
  Mit Zitat antworten Zitat
steewan

Registriert seit: 27. Nov 2003
20 Beiträge
 
#9

Re: Daten in einer Klassenhierachie ablegen

  Alt 1. Nov 2006, 22:08
Hallo,

vielleicht kann mir noch einmal jemand helfen. Beiliegender Programmcode erzeugt in folgender Prozedur eine Zugriffsverletzung:

Delphi-Quellcode:
procedure TStromkreis.Add_Leuchte(vAdresse : integer; vZielort: string);
var idx : integer;
vLeuchte : TLeuchte;
begin
idx := get_Anzahl_Leuchten + 1;
SetLength(FLeuchten, idx + 1);
vLeuchte := TLeuchte.create;
FLeuchten[idx] := vLeuchte;

FLeuchten[idx].Adresse := vAdresse;
FLeuchten[idx].Zielort := vZielort;
end;
Und ich habe leider keine Ahnung, warum dies so ist. Anscheinend existiert etwas nicht mehr die Länge von der Funktion get_Anzahl_Leuchten ist auf einmal ziemlich groß.

mfg
Stefan
Angehängte Dateien
Dateityp: zip zielorte4_105.zip (7,1 KB, 4x aufgerufen)
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#10

Re: Daten in einer Klassenhierachie ablegen

  Alt 1. Nov 2006, 22:10
FLeuchten[idx-1] := vLeuchte;
Markus Kinzler
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 06:59 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