Class types not related?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Class types not related?

Beitrag von dl5eu »

Hallo zusammen,

bisher habe ich mich noch nicht mit der Implementierung von Interfaces befasst. Soll heißen, das ist für mich Neuland, zumindest in Free Pascal. Deshalb wollte ich das Programm aus dem Wiki (https://wiki.freepascal.org/How_To_Use_Interfaces) kompilieren und damit etwas spielen. Beim Kompilieren bekomme ich aber in Zeile 69 an der Stelle "THook(FHook).Free;" eine Warnung, die ich nicht verstehe: "interfacesygenerics.lpr(69,5) Warning: Class types "ITestInterface" and "THook" are not related".

Würde mir bitte jemand von Euch verraten, was sie bedeutet? Inwiefern sind die beiden Klassen "not related"? THook ist doch die Implementierung von ITestInterface. Oder habe ich da etwas falsch verstanden?

Vielen Dank für Eure Hilfe!

Grüße,

Ralf

Warf
Beiträge: 1909
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Class types not related?

Beitrag von Warf »

Ich kenn mich da auch nicht so sehr aus, aber ist doch irgendwie sinnig. Sagen wir du hast 20 verschiedene Typen die vom selben Interface erben, THook(irgendwas) zu schreiben ist also in 19 von 20 fällen falsch. Darum macht ne warnung sinn. Au0erdem ist doch das genau der witz an interfaces, das du eben nicht wissen musst was für ein Typ unterliegt. Wenn du weißt das es ein THook ist, dann macht es überhaupt keinen sinn an dieser stelle ein Interface zu benutzen

Außerdem noch ein paar sachen.
1. Der destructor ist immer Virtual, d.h. du kannst einfach TObject(...).Free schreiben, das ist auf jeden fall korrekt (oder FreeAndNil benutzen)
2. Es gibt den As operator, der zur laufzeit (mittels RTTI) überprüft ob die Konvertierung auch Legal ist, d.h. ob der Pointer wirklich auf die entsprechende Instanz zeigt. Typ(...) ist rein zur kompilezeit und rein statisch, solang also performance nicht sonderlich relevant ist, gibt es keinen grund Typ(...) statt (... as Typ) zu schreiben, da das keinen fehler wirft, und im worst case ohne fehler einfach dein programm in einen undefinierten State bringt, sodass es komplett falsche sachen macht, du aber nicht rausfinden kannst wo der fehler liegt (ein fehler der dir um die Ohren fliegt ist eigentlich immer zu bevorzugen)
3. COM interfaces sind referenzgezählt, du kannst also auch ganz einfach den Ref counter implementieren, dann brauchst du gar kein Free mehr aufzurufen

dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Re: Class types not related?

Beitrag von dl5eu »

Hallo Warf,

Danke für Deine Erklärungen. Ich denke, das hilft mir schon mal weiter. In dem von Dir geschilderten Fall macht die Warnung tatsächlich Sinn.

Was den Ref-Counter betrifft reicht es doch, wenn ich bei der Implementierung eines Interfaces auch von TInterfacedObject oder einem Nachkommen erbe. Dann wird die Instanz freigegeben, sobald sie nicht mehr benötigt wird, richtig?

Grüße,

Ralf

Warf
Beiträge: 1909
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Class types not related?

Beitrag von Warf »

Code: Alles auswählen

Was den Ref-Counter betrifft reicht es doch, wenn ich bei der Implementierung eines Interfaces auch von TInterfacedObject oder einem Nachkommen erbe. Dann wird die Instanz freigegeben, sobald sie nicht mehr benötigt wird, richtig?


Ja wenn du erben kannst, dann ja. Manchmal (bei mir eigentlich immer) hab ich aber bereits schon oberklassen, die eventuell sogar gar nicht von mir sind (die ich dann entsprechend nicht einfach von TInterfacedObject ableiten kann) sodass ich es selbst implementieren muss.
aber, das gilt nur für interface referenzen, d.h. sobald du die irgendwo als nicht interface abspeicherst (z.B. in ner variable mit dem echten Klassentyp), wird dafür keine referenz gezählt
Wenn du das nicht willst kannst du einfach CORBA interfaces benutzen (am anfang der Unit {$Interfaces CORBA} schreiben, oder die Refenzzählermethoden mit noops überladen (also einfach nix machen)

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1435
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Class types not related?

Beitrag von fliegermichl »

Also die Meldung bekommst du normalerweise wenn du einen TypeCast machen willst mit 2 Klassen die nicht aus der gleichen Vererbungslinie stammen und somit auch nicht per TypeCast zugewiesen werden können.
Beispiel:

Code: Alles auswählen

 
type
 TClass1 = class
 end;
 
 TClass2 = class ( TClass1 ) // TClass2 erbt von TClass1
 end;
 
 TClass3 = class // Hier beginnt eine neue Klassenhirarchie
 end;
 
 TClass4 = class ( TClass3 )
 end;
 
procedure test;
var c1 : TClass1;
    c3 : TClass3;
begin
 c1 := TClass1.Create;
 c3 := TClass3(c1);
end;
 


Die Klassen TClass1 und TClass3 sind nicht von der gleichen Basisklasse abgeleitet und somit ist der Typecast falsch.
TClass1 und TClass2 sind in der gleichen Vererbungslinie. Somit kann eine Instanz von TClass2 auch an eine Variable vom Typ TClass1 zugewiesen werden.

Antworten