AGB  ·  Datenschutz  ·  Impressum  







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

Problem mit Interfaces

Ein Thema von hoika · begonnen am 2. Aug 2006 · letzter Beitrag vom 3. Aug 2006
Antwort Antwort
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#1

Problem mit Interfaces

  Alt 2. Aug 2006, 19:02
Hallo,

ich verzweifle gerade an Interfaces.

Das Problem ist die Stelle // XXX //
Danach wird der Speicher der lokalen Varaible TestId überschrieben.

Ich denke, der Fehler liegt im GetInterface.
Nur wie soll ich denn sonst ein Interface auf die Klasse bekommen ???.


Unteres Bsp führt zum Überschreiben der lokalen Variabel TestCode.
Was mache ich falsch ?

Ich will von dieser Basisklasse weg,
also bitte keine "pack das property doch in die Basisklasse"

Danke
Heiko

Delphi-Quellcode:
type
  IResource = interface
    function GetResType: Integer;

    property iResType: Integer
      read GetResType
  end;

type
  TBaseRes = class(TInterfacedClass)
    function GetInterface: IResource; virtual; abstract;
  end;

// Res1

type
  TRes1 = class(TBaseRes, IRes)
    function GetInterface: IResource; override;
    function GetResType: Integer;
  end;

function TRes1.GetInterface: IResource;
var
  IntRes: IResource;
begin
  IntRes:= Self;
  Result:= IntRes;
end;

function TRes1.GetResType: Integer;
begin
  Result:= 1;
end;

// Res2

type
  TRes2 = class(TBaseRes, IRes)
    function GetInterface: IResource; override;
    function GetResType: Integer;
  end;

function TRes2.GetInterface: IResource;
var
  IntRes: IResource;
begin
  IntRes:= Self;
  Result:= IntRes;
end;

function TRes2.GetResType: Integer;
begin
  Result:= 2;
end;

// problem code

var
  iResItem : Integer;
  ResItem : TBaseRes;
  IntRes : IResource;
  TestId : Integer;
begin
  TestId:= 100;

  for iResItem:= 0 to ResList.Count-1 do
  begin
    ResItem:= ResList[iResItem];

    IntRes:= ResItem.GetInterface;


  // XXX //
    if IntRes.iResType=1 do
    begin
      blaaa


   // TestId wurde verändert !!
  end;
Heiko
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#2

Re: Problem mit Interfaces

  Alt 2. Aug 2006, 22:40
Hallo,
Zitat von hoika:
Ich denke, der Fehler liegt im GetInterface.
Nur wie soll ich denn sonst ein Interface auf die Klasse bekommen ???.
Ich weiß jetzt nicht, wie intensiv Du Dich mit Interfaces beschäftigt, hast, aber da Interfaces in Delphi kein Sprachfeature sind, sondern COM-Interfaces, bekommst Du arge Probleme, wenn Du Interfaces und normale Klassen mischst.
Zitat von hoika:
Unteres Bsp führt zum Überschreiben der lokalen Variabel TestCode.
Was mache ich falsch ?
Ich kann im geposteten Code keine Ursache für dieses Problem finden, aber ein paar Stolperfallen (siehe ersten Kommentar).
Zitat von hoika:
Ich will von dieser Basisklasse weg,
also bitte keine "pack das property doch in die Basisklasse"
Dann schmeiß doch die Basisklasse weg. Wozu brauchst Du die?

Hier noch ein kleiner Link zu meinem Interface-Tutorial (ich poste das immer wieder gerne ).

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

Re: Problem mit Interfaces

  Alt 2. Aug 2006, 23:11
Zitat von xaromz:
aber da Interfaces in Delphi kein Sprachfeature sind, sondern COM-Interfaces
Was willst du damit sagen? Interfaces sind sehr wohl ein Sprachfeature von Delphi (C++ kennt keine Interfaces im aktuellen Standard, da werden abstrakte Klasse dafür "misbraucht"). Es kommt nur darauf an, was das dahintersteckende Objekt bei _AddRef und _Release Aufrufen macht. Hat man z.B. TInterfacedPersistent oder gar TComponent als Implementor-Basisklasse, kann man sehr wohl Interfaces und Objektreferenzen mischen. Man muss halt bei Interfaces wissen, was so im Hintergrund abläuft.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Problem mit Interfaces

  Alt 3. Aug 2006, 07:55
Hallo,

Das Problem beim Ersetzen ist ...

viiiiiieeeell Code. ;(


Es war ja nur als Bsp. gedacht.
Die dahinterliegenden Klassen sind "etwas" größer,
so ein paar tausend Zeilen müssen geändert und
vor allem getestet werden.

Ich will die nach und nach umstellen.
Dafür ist das GetInterface da.
Das <iResType> property war das erste, was ich umstellen wollte.
Das hatte ich in 3 Stunden erledigt.
Und dann kommt es jetzt zu diesem Speicherfehler.

Ich werde mir mal das Tutorial ansehen .

Mein Frage zielte ja darauf hin,
ob in dem Code ein prinzipieller Fehler ist.

Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.201 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: Problem mit Interfaces

  Alt 3. Aug 2006, 08:20
Zitat von hoika:
Mein Frage zielte ja darauf hin,
ob in dem Code ein prinzipieller Fehler ist.
Ich verstehe nicht wieso du eine gesonderte GetInterface-Methode benötigst und du nicht einfach mittels is und as auf dieses Interface zugreifst?
Auch ist das Mischen von Klassen und Interfacezugriffen problematisch. Hier gibt es eine Fall bei Delphi wo die automatische Referenzzählung durcheinander kommt und das Objekt schon freigegeben wird. Und dies ist vermutlich bei deiner GetInterface-Methode mit der lokalen Variable der Fall.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Problem mit Interfaces

  Alt 3. Aug 2006, 08:51
Hallo Bernhard,

meinst du

Delphi-Quellcode:
var
  iResItem : Integer;
  ResItem : TBaseRes;
  Res_1 : TRes1;
  IntRes : IResource;
  TestId : Integer;
begin
  TestId:= 100;

  for iResItem:= 0 to ResList.Count-1 do
  begin
    ResItem:= ResList[iResItem];

    if ResItem is TRes1 then
    begin
      Res_1:= ResList[iResItem];
    end;
??

Darauf bin ich ja noch gar nicht gekommen ...

Nach dem Lesen des Tutorials (speziell das Mischen von Klassen und Interfaces)
habe ich aber den alten Stand wieder ausgecheckt.


Ich wollte 3 völlig verschiedenen Klassen (Person,Arbeitsplatz,Fahrzeug)
mehrere neue gemeinsame Eigenschaften (Resourcentyp, Ressourcenname) zuordnen,
ohne sie von einer einzelnen Basisklasse abzuleiten.
Alle 3 Klassen haben aber selber schon ne Menge eigener Properties.
Deshalb dachte ich, Interfaces wären eine gute Idee.
Alle "Ressourcen" wurden dann in eine TList geladen und
über das gemeinsame Interface zugreifen.

Das war der Plan ..


Heiko
Heiko
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#7

Re: Problem mit Interfaces

  Alt 3. Aug 2006, 10:08
Hallo,
Zitat von jbg:
Was willst du damit sagen? Interfaces sind sehr wohl ein Sprachfeature von Delphi (C++ kennt keine Interfaces im aktuellen Standard, da werden abstrakte Klasse dafür "misbraucht"). Es kommt nur darauf an, was das dahintersteckende Objekt bei _AddRef und _Release Aufrufen macht. Hat man z.B. TInterfacedPersistent oder gar TComponent als Implementor-Basisklasse, kann man sehr wohl Interfaces und Objektreferenzen mischen. Man muss halt bei Interfaces wissen, was so im Hintergrund abläuft.
Damit will ich sagen, dass man eben nicht Klassen und Interfaces mischen kann, weil das so in Delphi nicht geplant war. Interfaces wurden "angebaut", anstatt sie richtig zu integrieren. Deshalb haben auch Interfaces eine Referenzzählung und Klassen nicht. Wenn man weiß, wie man damit umgeht, ist das kein Problem. Leider erledigt das aber eben nicht die Sprache (bzw. der Compiler) für Dich, sondern Du musst es selbst erledigen.
Schau Dir mal .Net an. Da kannst Du immer Klassen und Interfaces mischen, weil das in allen Sprachen von Anfang an so vorgesehen war (die Referenzzählung ist ja sowieso für den GC notwendig).

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#8

Re: Problem mit Interfaces

  Alt 3. Aug 2006, 10:42
Hallo,

gerade aus .Net hatte ich die Überlegung.
In einem Artikel des .net Magazins stand das mal drin.

Was mich stört ist, dass die Klasse zerstört wird,
wenn der Referenzzeiger 0 ist.

Naja, man sollte halt neue Sachen an einfachen Testprogrammem
ausprobieren. Ich hatte das gleich eingebaut ...


Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.201 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Problem mit Interfaces

  Alt 3. Aug 2006, 10:46
Zitat von xaromz:
Damit will ich sagen, dass man eben nicht Klassen und Interfaces mischen kann, weil das so in Delphi nicht geplant war. Interfaces wurden "angebaut", anstatt sie richtig zu integrieren. Deshalb haben auch Interfaces eine Referenzzählung und Klassen nicht. Wenn man weiß, wie man damit umgeht, ist das kein Problem. Leider erledigt das aber eben nicht die Sprache (bzw. der Compiler) für Dich, sondern Du musst es selbst erledigen.
In 99,9% der Fälle brauchst Du dich bei Interfaces nicht um die Referenzzählung kümmern da dies der Compile automatisch macht.

Zitat von xaromz:
Schau Dir mal .Net an. Da kannst Du immer Klassen und Interfaces mischen, weil das in allen Sprachen von Anfang an so vorgesehen war (die Referenzzählung ist ja sowieso für den GC notwendig).
Garbage Collection hat nicht unbedingt was mit Referenzzählung zu tun. Dies sind 2 paar Stiefel. Richtig ist das man bei einer Sprache mit GC sowohl bei Klassen(referenzen) und Interfaces sich nicht mehr um die freigabe kümmern muss.
GC über Referenzzählung ist nur eine möglicher Algorithmus für die Speicherfreigabe.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#10

Re: Problem mit Interfaces

  Alt 3. Aug 2006, 10:59
Hallo,
Zitat von Bernhard Geyer:
In 99,9% der Fälle brauchst Du dich bei Interfaces nicht um die Referenzzählung kümmern da dies der Compile automatisch macht.
Es ging hier um das Mischen von Objekten und Interfaces. Da muss man sich schon kümmern.
Zitat von Bernhard Geyer:
Garbage Collection hat nicht unbedingt was mit Referenzzählung zu tun. Dies sind 2 paar Stiefel. Richtig ist das man bei einer Sprache mit GC sowohl bei Klassen(referenzen) und Interfaces sich nicht mehr um die freigabe kümmern muss.
GC über Referenzzählung ist nur eine möglicher Algorithmus für die Speicherfreigabe.
Ich weiß, es ging mir auch eher darum, dass eben die Referenzzählung (oder was auch immer in .Net gemacht wird) der Interfaces nicht losgelöst vom eigentlichen Objekt funktioniert, sondern der selbe Mechanisums auch beim Objekt greift. Deshalb kann es auch nicht passieren, dass man sich ein Interface holt und dann automatisch das Objekt freigegeben wird, obwohl das nicht gewünscht war.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  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 10:42 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