AGB  ·  Datenschutz  ·  Impressum  







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

Handling von Objekten (vom Typ TObject)

Ein Thema von Yheeky · begonnen am 23. Jun 2008 · letzter Beitrag vom 24. Jun 2008
Antwort Antwort
Seite 1 von 2  1 2      
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#1

Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 19:33
Hey,

so, neue Frage, neuer Thread

Ich beschäftige mich zur Zeit ein bisschen mit der Klasse TObject. Ich weiss jedoch leider noch nicht so recht wie genau man mit Objekten umgeht. Habe schon ein Tutorial gelesen, aber scheinbar mache ich hin und wieder etwas falsch, weil sich bei mir desöfteren Zugriffsverletzungen ereignen.
Unklar ist mir z.B. wann ich

Obj := TObject.Create; benutze und wann ich einfach ohne oben angegebene Zeile

Obj := dummyFunction(getObj(Param)); verwende.

Ein paar grundlegende Infos wären super!

Danke schonmal!
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 19:40
Moin Christian,

im ersten Falle erzeugst Du das Objekt, und die Variable bekommt dann die Referenz auf die erzeugte Instanz, damit Du damit arbeiten kannst.

Mit dem zweiten Fall kann ich nichts anfangen
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 19:41
TObject ist die Mutter aller Klassen. D.h. jede Klasse in Delphi erbt von ihr.

Obj := TObject.Create; Erzeugt eine neue Instanz
Markus Kinzler
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#4

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 20:01
Okay, ein anderes Beispiel

Delphi-Quellcode:
var tempAuto : TAuto;
begin
tempAuto := TAuto.Create;
tempAuto := autoSammlung.GetAutoByName('Opel');

tempAuto.Free;
Erstens wurde mir gesagt, dass ich TAuto.Create; nicht ausführen muss, zweitens, dass ich es in der zweiten Zeile wieder überschreibe und drittens bekomme ich bei tempAuto.Free; eine Zugriffsverletzung.

Zu den Punkten:
1.) Warum muss ich es nicht immer ausführen, wenn es doch "die Mutter aller Klassen" ist?
2.) Warum überschreibe ich tempAuto hier? Ich dachte ich hätte über Create die Instanz erstellt und würde ihr in der zweiten Zeile einfach ein Objekt zuweisen.
3.) Warum kann ich das Objekt auf diese Weise nicht einfach freigeben?

So, das sind jetzt erstmal ein paar Fragen
  Mit Zitat antworten Zitat
Benutzerbild von OldGrumpy
OldGrumpy

Registriert seit: 28. Sep 2006
Ort: Sandhausen
941 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 20:07
Wie schon oben gesagt, mit TObject.Create erzeugst Du eine neue Instanz - wenn Du das dreimal machst, hast Du am Ende drei eigenständige Objekte. Von denen muss auch jedes am Ende wieder abgeräumt werden (mittels FreeAndNil() oder TObject.Free, je nachdem, mein Tipp dazu: Verwende wo es geht FreeAndnil).

Der zweite Fall soll - vermute ich mal - das Weiterreichen einer Instanz symbolisieren. Dabei wird kein neues Objekt erzeugt, sondern nur eine Art Verweis auf ein bereits existierendes Objekt "nach draussen gereicht". Dieser Verweis, auch Pointer genannt, ermöglicht es Dir, von praktisch überall her auf das Objekt zuzugreifen.

Ganz wichtig: Wenn Du mit diesen Verweisen arbeitest, musst Du sehr genau hinschauen, wer das Objekt am Ende wieder freigeben darf! Wenn das Objekt freigegeben wird, hat das keine Auswirkungen auf den Pointer, jedoch wird ein Zugriff über den Pointer auf das bereits abgeräumte Objekt meist mit einer Zugriffsverletzung "belohnt". Je nach Programm kann auch zuerst *anscheinend* alles glatt gehen, aber im Speicher kann dabei ziemliches Chaos angerichtet werden, was früher oder später das Programm zum Absturz bringt - oder zumindest zu seltsamem Verhalten bringt.

Eine überall gültige Regel, welche Seite das Objekt, auf das der Pointer zeigt, wieder freigeben darf, gibt es nicht. In der Regel sagt man aber, wer es angelegt hat, sollte es auch wieder abräumen. Ausnahmen sind zum Beispiel Objekte, die zwar "auf der einen Seite" erzeugt werden, dann aber nur auf der "anderen Seite" benutzt werden. Hier macht es Sinn, das Objekt dann auch auf "der anderen Seite" abzuräumen wenn es nicht mehr benötigt wird.

//EDIT: Roter Kasten

Nachtrag: Ohne TAuto zu kennen, können diese Fragen nicht beantwortet werden, da die Antworten von der Implementation von TAuto abhängen.
"Tja ja, das Ausrufezeichen... Der virtuelle Spoiler des 21. Jahrhunderts, der Breitreifen für die Datenautobahn, die k3wle Sonnenbrille fürs Usenet. " (Henning Richter)
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 20:10
Zitat:
1.) Warum muss ich es nicht immer ausführen, wenn es doch "die Mutter aller Klassen" ist?
tempAuto := autoSammlung.GetAutoByName('Opel');
Gibt eine Referenz auf eine vorhandenes Objekt zurück. Deshalb ist der Konstruktoraufruf überflüssig, denn sonst hättest du ja eine leere Instanz zuviel.
Zitat:
2.) Warum überschreibe ich tempAuto hier? Ich dachte ich hätte über Create die Instanz erstellt und würde ihr in der zweiten Zeile einfach ein Objekt zuweisen.
Es handelt sich bei tempAuto um eine Referenz-Variable ( Zeiger)
Zitat:
3.) Warum kann ich das Objekt auf diese Weise nicht einfach freigeben?
Das Objekt wird ja vom Objekt autoSammlung verwaltet
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#7

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 20:46
Zitat von Yheeky:
2.) Warum überschreibe ich tempAuto hier? Ich dachte ich hätte über Create die Instanz erstellt und würde ihr in der zweiten Zeile einfach ein Objekt zuweisen.
Um es nochmal deutlich zu machen: Instanz und Objekt bedeuten dasselbe! Du weist der Variablen also ein neues Objekt zu und in der nächsten Zeile wieder eins. Damit ist das erste im Speicher-Nirvana: Es gibt keine Referenz mehr darauf, also kann es nicht mehr freigegeben werden.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 21:45
Moin Zusammen,

und um das von den anderen schon gesagte noch zu ergänzen:
Um solche Probleme zu umgehen, sollte man nie Objekte als Rückgabewert einer Funktion verwenden, da dann immer das Problem besteht, die Freigabe korrekt zu positionieren.
So wäre es übersichtlicher:

Delphi-Quellcode:
var
  tempAuto : TAuto;

begin
  tempAuto := TAuto.Create;
  try
    // Das Objekt, bzw. die Instanz mit Daten füllen
    autosammlung.GetAutoByName('Opel',tempAuto);
    // mit dem Objekt (tempAuto) arbeiten
    //...
  finally
    tempAuto.Free;
    // oder
    FreeAndNil(tempAuto);
  end;
end;

// So könnte dann die Methode deklariert werden.
// Statt eines Results vom Typ TAuto, wird eine Instanz von TAuto übergeben
procedure TAutoSammlung.GetAutoByName(const AsTyp : string;const AResult : TAuto);
begin
  // Hier nun die Daten holen und in AResult ablegen
  // Ein Create darf hier nicht mehr erfolgen!
  // AResult ist als const deklariert, damit man nicht versehentlich
  // eine weitere Instanz zuweist.
end;
Es gibt zwar auch Methoden, die ein Objekt zurückgeben (z.B. TListView.Add gibt ein Objekt vom Typ TListItem zurück), aber in diesem Falle verwaltet auch die Klasse (hier TListView) selber die Objekte (TListItem).
Solange man das nicht selber auch so macht, und die Objektinstanzen einzeln erzeugt, sollte man keine Objekt als Ergebnis zurückgeben (wie weiter oben schon erwähnt).
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
dominikkv

Registriert seit: 30. Sep 2006
Ort: Gundelfingen
1.109 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 22:03
Du musst dir ein Object, wenn du es so deklarierst
Delphi-Quellcode:
var
  MyObj: TMyObject;
so vorstellen:

- Du hast erstmal ein Speicherbereich (Heap), auf dem die ganzen Eigenschaften (Felder) gespeichert werden
- Außerdem hast du einen Zeiger auf diesen Bereich

Am Anfang ist nur der Zeiger da, der halt irgendwo hin zeigt (NIL - Not In List). Dieser Zeiger wird am Anfang der Procedure erstellt und am Ende der Procedure wieder gelöscht.
Um jetzt mit dem Objekt arbeiten zu können musst du dir erstmal dein Speicherbereich auf dem Heap reservieren und den Zeiger darauf setzen. Das erledigst du mit dem sogenannten Konstructor:
MyObj := TMyObject.Create; Das ist immer zwingend notwendig, wenn du auf einen Zeiger zugreifst der nirgendwohin zeigt gibts ne Zugriffsverletzung.
Jetzt kannst du dir zB ein Object erstellen und mehrere Zeiger darauf haben:
Delphi-Quellcode:
var
  MyObj1, MyObj2: TMyObject;
begin
  MyObj1 := TMyObject.Create; // Speicherplatz reservieren und Zeiger MyObj1 ausrichten
  MyObj2 := MyObj1; // Auch noch den 2ten Zeiger ausrichten


  MyObj2.Eigenschaft := 'Bla';
  MyObj1.Eigenschaft := 'Hallo';
  Showmessage(MyObj2.Eigenschaft); // Da wir auf den gleichen Speicherbereich zugreifen kommt "Hallo"
  MyObj2.Free; // Den reservierten Speicherplatz wieder freigeben

  TMyObject.Create; // auch das ist möglich, blöderweise haben wir dann kein zeiger darauf -.-
end;
Das .free nicht vergessen, da der reservierte Speicherbereich sonst im Heap bleibt und erst am Ende, wenn das Programm beendet wird, freigegeben wird (-> Speicherleck).

Bei deiner oben genannten Funktion werden nur die Zeiger weitergegeben, da diese Zeiger schon auf einen Speicherbereich zeigen musst du in diesem Fall den Konstructor und Destructor (free) weglassen.
Nochmal ganz konkret: Mit dem Konstructor reservierst du Speicher und setzt deinen Zeiger darauf, bei deiner Funktion ist der Speicher schon da und du veränderst nur den Zeiger.
Dominik
Wer anderen eine Grube gräbt, hat ein Gruben-Grab-Gerät!
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#10

Re: Handling von Objekten (vom Typ TObject)

  Alt 23. Jun 2008, 22:56
Jungs, ihr seid super! Dank euren Beispielen glaube ich den Großteil verstanden zu haben. Ich hoffe ich kann´s nun in meinem Programm richtig benutzen
DANKE!
  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 18:15 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