Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem mit Vererbung (https://www.delphipraxis.net/100628-problem-mit-vererbung.html)

xZise 1. Okt 2007 18:20


Problem mit Vererbung
 
Ich wollte folgende Grundkronstruktion verwenden:
Delphi-Quellcode:
TTab = class(TObject)
private
  FSheet: TTabSheet;
  FTabs : TTabs;

  procedure SetSheet(const Value: TTabSheet);
published
  property Sheet : TTabSheet read FSheet write SetSheet;
  property Tabs : TTabs read FTabs;
public
  constructor Create(const APageControl : TPageControl);
  destructor Destroy;
end;
Nun soll es davon 2 verschiedene Tabtypen geben:
Delphi-Quellcode:
TMemoTab = class(TTab)

end;

TExplorerTab = class(TTab)

end;
Funktioniert soweit.
Nun habe ich auch eine Liste:
Delphi-Quellcode:
TTabs = class(TObject)
private
  FTabs : TObjectList;
end;
Nun soll TTab keine Funktionen haben.
Also habe ich alle Funktionen als "virtual; abstract;" bezeichnet.

Wenn ich nun der Tabliste ein Tab hinzufüge mit folgender Funktion:
Delphi-Quellcode:
procedure TTabs.Add(const ATab: TTab);
begin
  FTabs.Add(ATab);
  ATab.FTabs := self;
end;
Dann gibt es dort einen Abstrakten Fehler.

Wenn ich nun die nicht als abstrakt bezeichne und "Quasileerfunktionen" einsetze, dann habe ich das Problem in der Add-Funktion, ATab nicht mehr "aktuell" ist.
Folgender Aufruf (Tabs : TTabs):
Delphi-Quellcode:
Tabs.Add(TExplorerTab.Create(pcTabs, CreatePath(Node)));
Alles wunderbar... Jedenfalls scheint es so.
Wenn ich jetzt in der Add-Methode die Caption des TabSheets ändere, dann hat es keine Auswirkungen:
Delphi-Quellcode:
procedure TTabs.Add(const ATab: TTab);
begin
  FTabs.Add(ATab);
  ATab.FSheet.Caption := 'BOM!';
  // Oder auch so (Die Add-Methode darüber wird entfernt):
  (FTabs.Items[FTabs.Add(ATab)] as TTab).FSheet.Caption := 'BOM!';

  ATab.FTabs := self;
end;
Wo liegt nun der Fehler?
Wenn ihr noch Informationen braucht, dann sagt bitte welche, damit ich die nachliefern kann :)

MfG
xZise

PS: Die TTabs Klasse:
Delphi-Quellcode:
TTabs = class(TObject)
private
  FTabs : TObjectList;
  FIcons : TIconList;
  FFileToolBar: TToolBar;
  FDirectoryToolBar: TToolBar;

  function GetTab(idx: Integer): TTab;
  procedure SetTab(idx: Integer; const Value: TTab);
public
  property Tab[idx : Integer] : TTab read GetTab write SetTab;
  property FileToolBar : TToolBar read FFileToolBar write FFileToolBar;
  property DirectoryToolBar : TToolBar read FDirectoryToolBar write FDirectoryToolBar;

  procedure Add(const ATab : TTab);
  procedure Delete(const AIndex : Integer);

  constructor Create;
  destructor Destroy; override;
end;

shmia 1. Okt 2007 19:13

Re: Problem mit Vererbung
 
Zitat:

Zitat von xZise
Nun habe ich auch eine Liste:
Delphi-Quellcode:
TTabs = class(TObject)
private
  FTabs : array of TTab;
end;

Das ist keine Liste. Nimm doch TObjectList aus Unit contnrs!

Progman 1. Okt 2007 19:30

Re: Problem mit Vererbung
 
außerdem hats du in TTab bereits FTabs deklariert, vielleicht kommt da was durcheinander?

xZise 1. Okt 2007 21:33

Re: Problem mit Vererbung
 
Zitat:

Zitat von shmia
Zitat:

Zitat von xZise
Nun habe ich auch eine Liste:
Delphi-Quellcode:
TTabs = class(TObject)
private
  FTabs : array of TTab;
end;

Das ist keine Liste. Nimm doch TObjectList aus Unit contnrs!

OOPs ^^ Nein ;) Es ist ja gerade eine ObjectListe :)

Zitat:

Zitat von Progman
außerdem hats du in TTab bereits FTabs deklariert, vielleicht kommt da was durcheinander?

Genau dieses FTabs will ich haben ;)
Damit der Tab nachher "weis" in welcher Liste der gehört, um selber für die Tabliste Tabs zu erzeugen.

Hier ist nochmal TTabs ^^
Delphi-Quellcode:
TTabs = class(TObject)
private
  FTabs : TObjectList;
  FIcons : TIconList; // wird nicht verwendet
  FFileToolBar: TToolBar;
  FDirectoryToolBar: TToolBar;

  function GetTab(idx: Integer): TTab;
  procedure SetTab(idx: Integer; const Value: TTab);
public
  property Tab[idx : Integer] : TTab read GetTab write SetTab;
  property FileToolBar : TToolBar read FFileToolBar write FFileToolBar;
  property DirectoryToolBar : TToolBar read FDirectoryToolBar write FDirectoryToolBar;

  procedure Add(const ATab : TTab);
  procedure Delete(const AIndex : Integer);

  constructor Create;
  destructor Destroy; override;
end;

Muetze1 2. Okt 2007 11:21

Re: Problem mit Vererbung
 
Zitat:

Zitat von xZise
Wenn ich nun der Tabliste ein Tab hinzufüge mit folgender Funktion:
Delphi-Quellcode:
procedure TTabs.Add(const ATab: TTab);
begin
  FTabs.Add(ATab);
  ATab.FTabs := self;
end;
Dann gibt es dort einen Abstrakten Fehler.

Nur, wenn du eine TTab Instanz übergibst anstatt z.B. einer TExplorerTab Instanz.

Zitat:

Zitat von xZise
Wenn ich nun die nicht als abstrakt bezeichne und "Quasileerfunktionen" einsetze, dann habe ich das Problem in der Add-Funktion, ATab nicht mehr "aktuell" ist.
Folgender Aufruf (Tabs : TTabs):
Delphi-Quellcode:
Tabs.Add(TExplorerTab.Create(pcTabs, CreatePath(Node)));
Alles wunderbar... Jedenfalls scheint es so.
Wenn ich jetzt in der Add-Methode die Caption des TabSheets ändere, dann hat es keine Auswirkungen:
Delphi-Quellcode:
procedure TTabs.Add(const ATab: TTab);
begin
  FTabs.Add(ATab);
  ATab.FSheet.Caption := 'BOM!';
  // Oder auch so (Die Add-Methode darüber wird entfernt):
  (FTabs.Items[FTabs.Add(ATab)] as TTab).FSheet.Caption := 'BOM!';

  ATab.FTabs := self;
end;

Wird denn im Constructor von TTab auch ordentlich FSheet entsprechend belegt mit auch der Instanz wo du die Caption Änderung erwartest?

Das vergessene Override beim Destruktor hast du ja nun schon ergänzt...

xZise 2. Okt 2007 14:56

Re: Problem mit Vererbung
 
Hi,
Zitat:

Zitat von Muetze1
Zitat:

Zitat von xZise
Wenn ich nun der Tabliste ein Tab hinzufüge mit folgender Funktion:
Delphi-Quellcode:
procedure TTabs.Add(const ATab: TTab);
begin
  FTabs.Add(ATab);
  ATab.FTabs := self;
end;
Dann gibt es dort einen Abstrakten Fehler.

Nur, wenn du eine TTab Instanz übergibst anstatt z.B. einer TExplorerTab Instanz.

Aber warum funktioniert das denn nicht? TExplorerTab ist do ein Nachfahre von TTab? Müsste ich also die Funktio überladen?
Weil bei TStrings funktionierts ja auch :)
Delphi-Quellcode:
var
  sl : TStrings;
begin
  {...}
  sl := TStringList.Create;
  ini.ReadSections(sl);
  {...}
end;
Zitat:

Zitat von Muetze1
Zitat:

Zitat von xZise
Wenn ich nun die nicht als abstrakt bezeichne und "Quasileerfunktionen" einsetze, dann habe ich das Problem in der Add-Funktion, ATab nicht mehr "aktuell" ist.
Folgender Aufruf (Tabs : TTabs):
Delphi-Quellcode:
Tabs.Add(TExplorerTab.Create(pcTabs, CreatePath(Node)));
Alles wunderbar... Jedenfalls scheint es so.
Wenn ich jetzt in der Add-Methode die Caption des TabSheets ändere, dann hat es keine Auswirkungen:
Delphi-Quellcode:
procedure TTabs.Add(const ATab: TTab);
begin
  FTabs.Add(ATab);
  ATab.FSheet.Caption := 'BOM!';
  // Oder auch so (Die Add-Methode darüber wird entfernt):
  (FTabs.Items[FTabs.Add(ATab)] as TTab).FSheet.Caption := 'BOM!';

  ATab.FTabs := self;
end;

Wird denn im Constructor von TTab auch ordentlich FSheet entsprechend belegt mit auch der Instanz wo du die Caption Änderung erwartest?

Nein, aber der Konstruktor von TExplorer/MemoTab, welche ich ja ausschließlich übergebe.

Zitat:

Zitat von Muetze1
Das vergessene Override beim Destruktor hast du ja nun schon ergänzt...

Selbst wenn würde es keinen Fehler verursachen, da Explizit nirgends .Free aufgerufen wird.

MfG
xZise

Muetze1 2. Okt 2007 16:04

Re: Problem mit Vererbung
 
Zitat:

Zitat von xZise
Aber warum funktioniert das denn nicht? TExplorerTab ist do ein Nachfahre von TTab? Müsste ich also die Funktio überladen?

Die Exception wird geschmissen, wenn es auch nur eine noch abstracte Methode in der Klasse gibt. Also: hast du wirklich alle abstracte Methoden überschrieben (und implementiert)?

Zitat:

Zitat von xZise
Nein, aber der Konstruktor von TExplorer/MemoTab, welche ich ja ausschließlich übergebe.

Wenn du eine AV bekommst, dann schau im Debugger nach, was den nil ist. Also ob fSheet wirklich assigned ist etc. Auch kannst du bei unklarer Gesamtlage mit Debug-DCUs dein Projekt neu erstellen und dann in die VCL debuggen um zu schauen wo die Exception herkommt.

Zitat:

Zitat von xZise
Selbst wenn würde es keinen Fehler verursachen, da Explizit nirgends .Free aufgerufen wird.

Kein Fehler, nur (ein) Speicherleck(s)...

xZise 2. Okt 2007 16:11

Re: Problem mit Vererbung
 
Zitat:

Zitat von Muetze1
Zitat:

Zitat von xZise
Aber warum funktioniert das denn nicht? TExplorerTab ist do ein Nachfahre von TTab? Müsste ich also die Funktio überladen?

Die Exception wird geschmissen, wenn es auch nur eine noch abstracte Methode in der Klasse gibt. Also: hast du wirklich alle abstracte Methoden überschrieben (und implementiert)?

Das Hauptproblem ist selbst ohne abstrakten Methoden funktioniert das nicht :) Oder müssen die nun abstrakt sein, damit er auch die richtige Methode aufruft?

Zitat:

Zitat von Muetze1
Zitat:

Zitat von xZise
Nein, aber der Konstruktor von TExplorer/MemoTab, welche ich ja ausschließlich übergebe.

Wenn du eine AV bekommst, dann schau im Debugger nach, was den nil ist. Also ob fSheet wirklich assigned ist etc. Auch kannst du bei unklarer Gesamtlage mit Debug-DCUs dein Projekt neu erstellen und dann in die VCL debuggen um zu schauen wo die Exception herkommt.

Laut Debugger ist in der AddFunktion "FSheets" und ehm "FTabs" nil

Zitat:

Zitat von Muetze1
Zitat:

Zitat von xZise
Selbst wenn würde es keinen Fehler verursachen, da Explizit nirgends .Free aufgerufen wird.

Kein Fehler, nur (ein) Speicherleck(s)...

Achso :) Naja die Speicherlecks kann man nur beheben, wenn es funktioniert xD

So ! Ich habe jetzt TTab komplett "deabstrahiert" xD und die Add Methode überladen (mit TMemoTab und TExplorerTab)
So funktionierts, aber das war nicht der Zweck des Vererben :)

MfG
xZise

Muetze1 2. Okt 2007 16:20

Re: Problem mit Vererbung
 
Zitat:

Zitat von xZise
Das Hauptproblem ist selbst ohne abstrakten Methoden funktioniert das nicht :) Oder müssen die nun abstrakt sein, damit er auch die richtige Methode aufruft?

Was bedeutet dabei nun "funktioniert nicht"? Wenn ich wieder auf die alte Aussage schliesse (abstrakter Fehler), dann kann dies in dem Falle nicht mehr sein.

Zitat:

Zitat von xZise
Laut Debugger ist in der AddFunktion "FSheets" und ehm "FTabs" nil

Dann wird nicht der richtige Constructor aufgerufen. Somit ist die Frage von inherited etc. gegeben. Schonmal den Konstruktoraufruf im Add() debuggt? Wenn du in die Zeile mit F7 hineinstoperst, dann solltest du durch den entsprechenden Konstruktor (nach dem die Ermittlung der Parameter abgehandelt wurde) kommen, welcher dann nach deinem Quellcode und Aussagen doch eigentlich FSheets und FTabs initialisiert. Wenn dem nicht so ist, dann ist das nicht der Constructor. (wobei ich die Konstruktoren von den beiden abgeleiteten Klassen nicht kenne)

Zitat:

Zitat von xZise
So ! Ich habe jetzt TTab komplett "deabstrahiert" xD und die Add Methode überladen (mit TMemoTab und TExplorerTab)
So funktionierts, aber das war nicht der Zweck des Vererben :)

Das ist auch nicht das gewollte und dein vorgestelltes Konzept klappt auch 100%ig so wie du es vorhast. Es ist ein anderes Problem. Diese Lösung musst du nicht weiter verfolgen/benutzen.

r2c2 2. Okt 2007 16:28

Re: Problem mit Vererbung
 
Meine Glaskugel meint, es könnten n paar override; fehlen...

mfg

Christian


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:57 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz