Autor |
Beitrag |
glotzer
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 23.06.13 11:13
Hallo,
Ich hab ein Problem mit der Vererbung in Lazarus,
ich bin jetzt seit 2 Tagen am rumprobieren und finde einfach keine Lösung.
Google kann mir leider auch nicht helfen (wahrscheinlich verwende ich die falschen Suchbegriffe)
Mein Problem ist eigentlich sehr einfach, ich habe 3 Klassen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| type TA = class public procedure x; virtual; abstract; end;
TB = class(TA) public procedure x; override; end;
TC = class(TB) public procedure m; end;
D = class of TA; |
Wenn ich jetzt x so aufrufe:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var obj: TA; Objclass: D; begin Objclass := TC; obj := Objclass.Create; obj.x; obj.Free; end; |
kommt der Fehler x sei abstract und nicht implementiert (genauer : )
Ich kann in der Klasse TB auch keine Haltepunkte setzen, es scheint als würde der Compiler die Klasse ignorieren.
Das abschalten der Optimierung hat auch nicht geholfen.
Ich vermute es liegt irgendwie an der Klassenreferenz...
Vieleicht hat ja hier jemand eine tolle Idee, würd mich freuen
Grüße
Glotzer
_________________ ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
Zuletzt bearbeitet von glotzer am So 23.06.13 11:48, insgesamt 1-mal bearbeitet
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 23.06.13 11:47
Ich glaube du meinst eher: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var obj: TA; Objclass: D; begin Objclass := TC; obj := Objclass.Create; obj.x; obj.Free; end; |
|
|
glotzer 
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 23.06.13 11:49
ups ja, danke.
Allerdings nur hier ein kleiner Tippfehler, im eigentlichen Programm ist es schon richtig.
_________________ ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 23.06.13 13:50
Dann hast du wohl eine alte Version von Lazarus. In Version 1.0.10 funktioniert das problemlos, genau wie in Delphi.
|
|
glotzer 
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 23.06.13 13:55
hmm ich verwende 1.0.8.
Danke für deine Mühe ich versuchs mal mit nem Update.
_________________ ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: So 23.06.13 14:26
Entschuldige, aber Du definierst ja auch obj als TA:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var obj: TA; <=== Objekt hat TA-Klasse Objclass: D; begin Objclass := TC; obj := Objclass.Create; obj.x; obj.Free; end; |
wie wäre es denn, wenn Du das schreibst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var obj: TC; begin obj := TC.Create; obj.x; obj.Free; end; |
Ich benutze als einer Komponente TStringgrid ja auch nicht TCustomGrid als Klassenzuordnung für die Komponente sondern eben TStringgrid.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
Zuletzt bearbeitet von Tranx am So 23.06.13 14:36, insgesamt 3-mal bearbeitet
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: So 23.06.13 14:26
Mich wundert grade etwas, dass das wieder geht
Eigentlich war das mal sehr lange so, dass der Konstruktor einer Klasse, die per Klassenreferenz erzeugt wird, virtuell sein muss. Im Beispiel würde sonst immer TA.Create aufgerufen werden, weil die Referenz da hin zeigt.
Übrigens ist Laz 1.1 und FPC 2.7.1 aktuell. Sollte man mal updaten (ggf. auch auf Snapshots). Man kennt das heute gar nicht mehr, aber bei denen wird wirklich aktiv entwickelt, da sind 4 Wochen nicht aktualisiert eine halbe Welt.
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
glotzer 
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 23.06.13 14:42
Hab grad noch keine Zeit gehabt zu Updaten, aber:
Tranx hat folgendes geschrieben : |
wie wäre es denn, wenn Du das schreibst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var obj: TC; begin obj := TC.Create; obj.x; obj.Free; end; |
Ich benutze als einer Komponente TStringgrid ja auch nicht TCustomGrid als Klassenzuordnung für die Komponente sondern eben TStringgrid. |
Würd ich ja gerne aber kann ich nicht, sonst könnte ich mir die komplette Nummer mit der Klassenreferenz sparen.
Es geht darum, dass abhängig von einer Usereingabe Objekte verschiedener Klassen erzeugt werden, welche sich vorher Registriert haben. Ich weiß zur Designzeit nur, dass sie alle von der selben Klasse abgeleitet sind.
Martok hat folgendes geschrieben : | Mich wundert grade etwas, dass das wieder geht
Eigentlich war das mal sehr lange so, dass der Konstruktor einer Klasse, die per Klassenreferenz erzeugt wird, virtuell sein muss. Im Beispiel würde sonst immer TA.Create aufgerufen werden, weil die Referenz da hin zeigt. |
Er ist virtuell.
Martok hat folgendes geschrieben : |
Übrigens ist Laz 1.1 und FPC 2.7.1 aktuell. Sollte man mal updaten (ggf. auch auf Snapshots). Man kennt das heute gar nicht mehr, aber bei denen wird wirklich aktiv entwickelt, da sind 4 Wochen nicht aktualisiert eine halbe Welt. |
Wird gemacht, danke.
_________________ ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 23.06.13 14:46
Martok hat folgendes geschrieben : | Eigentlich war das mal sehr lange so, dass der Konstruktor einer Klasse, die per Klassenreferenz erzeugt wird, virtuell sein muss. Im Beispiel würde sonst immer TA.Create aufgerufen werden, weil die Referenz da hin zeigt. |
Das ist auch so, aber wenn man z.B. gar keinen Konstruktor in TB hat, ist es ja korrekt, dass der des Vorfahren aufgerufen wird.
Wenn man natürlich einen in der abgeleiteten Klasse definiert, kann man den der Elternklasse nicht überschreiben, wenn der nicht als virtuell definiert ist.
|
|
glotzer 
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 23.06.13 14:55
Gerade geupdated, keine Änderung, weiterhin das selbe Problem.
Ich versuch mal ein möglichst kleines Testprojekt zu machen.
_________________ ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 23.06.13 15:30
Ein Testprojekt ist natürlich das beste, aber du kannst auch erstmal die konkreten Deklarationen posten, die du im echten Projekt benutzt, die müssen ja so nicht kompilierbar sein.
|
|
glotzer 
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 23.06.13 16:47
Ich poste hier jetzt nur das entscheidende, ein komplettes Projekt ist im Anhang, es (sollte) auch kompilierbar sein.
main:
Delphi-Quelltext 1: 2: 3: 4: 5:
| var GUI: TBasicGUI; begin GUI := CreateGUISystem(GUI_Systems.Items[GUISelBox.ItemIndex]); end; |
basicGUI:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
| type
TBasicGUI = class(TStringList) public constructor Create; virtual; destructor Destroy; override; end;
type TBasicGUIClass = class of TBasicGUI; TBasicGUIList = specialize TFPGList<TBasicGUIClass>;
var GUI_Systems: TBasicGUIList;
function CreateGUISystem(ASystem: TBasicGUIClass): TBasicGUI; procedure RegisterGUISystem(ASystem: TBasicGUIClass);
implementation
function CreateGUISystem(ASystem: TBasicGUIClass): TBasicGUI; begin result := ASystem.create; end;
procedure RegisterGUISystem(ASystem: TBasicGUIClass); begin GUI_Systems.Add(ASystem); end;
constructor TBasicGUI.Create; begin inherited Create; showmessage('a'); end;
destructor TBasicGUI.Destroy; begin inherited Destroy; end;
initialization GUI_Systems := TBasicGUIList.Create;
finalization GUI_Systems.Free; |
basicguiform:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| type
TBasicFormGUI = class(TBasicGUI) public constructor Create; override; destructor Destroy; override; end;
{$R *.lfm}
implementation
constructor TBasicFormGUI.Create; begin inherited Create; showmessage('b'); end;
destructor TBasicFormGUI.Destroy; begin inherited Destroy; end; |
gui_Tiatai:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| type TTiatai = class(TBasicFormGUI) public a: integer; end;
implementation
initialization RegisterGUISystem(TTiatai); |
Problem ist, dass nur "a" angezeigt wird, niemals "b". Es sollte beides angezeigt werden.
Einloggen, um Attachments anzusehen!
_________________ ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 23.06.13 18:14
Du hast TBasicFormGUI doppelt deklariert...
Das mit dem Showmessage b aus basicguiform.pas wird nie benutzt, sondern das aus basicformgui.pas.
Für diesen Beitrag haben gedankt: glotzer
|
|
glotzer 
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 23.06.13 18:18
WOW, da muss man erstmal drauf kommen! vielen vielen Dank! Ich wär da wohl noch ewig davor gesessen ^^
_________________ ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
|
|
|