Autor Beitrag
glotzer
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: 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:
ausblenden 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; virtualabstract;
  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:
ausblenden 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 :
Zitat:
RunError(211)
)

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 :D

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 23.06.13 11:47 
Ich glaube du meinst eher:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: So 23.06.13 14:26 
Entschuldige, aber Du definierst ja auch obj als TA:

ausblenden 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:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
  obj: TC;  // korrekte Klassenzuordnung
//  Objclass: D;
begin
//  Objclass := TC;
  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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: So 23.06.13 14:42 
Hab grad noch keine Zeit gehabt zu Updaten, aber:



user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:

wie wäre es denn, wenn Du das schreibst:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
  obj: TC;  // korrekte Klassenzuordnung
//  Objclass: D;
begin
//  Objclass := TC;
  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.



user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
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.



user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:

Ü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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 23.06.13 14:46 
user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
  GUI: TBasicGUI; 
begin
  GUI := CreateGUISystem(GUI_Systems.Items[GUISelBox.ItemIndex]);
end;


basicGUI:
ausblenden volle Höhe 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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
type
  { TBasicGUI }

  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:
ausblenden 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 }

  TBasicFormGUI = class(TBasicGUI)
    public
      constructor Create; override;
      destructor Destroy; override;
  end;

  {$R *.lfm}

implementation

{ TBasicFormGUI }

constructor TBasicFormGUI.Create;
begin
  inherited Create;
  showmessage('b');
end;

destructor TBasicFormGUI.Destroy;
begin
  inherited Destroy;
end;


gui_Tiatai:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type
  { TTiatai }
  TTiatai = class(TBasicFormGUI)
  public
    a: integer;
  end;

implementation


{ TTiatai }

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: 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