AGB  ·  Datenschutz  ·  Impressum  







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

Zugriff auf Unterklasse absichern

Ein Thema von norwegen60 · begonnen am 2. Aug 2017 · letzter Beitrag vom 2. Aug 2017
Antwort Antwort
Seite 2 von 3     12 3      
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#11

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 11:46
Destructor Destroy natürlich immer "override". "reintroduce" unterdrückt zwar die Warnung des Compilers wenn "override" vergessen wurde. Das führt aber dazu, das dieser Destructor z.B. beim Aufruf von Free nicht aufgerufen wird.

Ein Beispiel für eine Lösung mit Nullobject:
Delphi-Quellcode:
  TMethode = class
  protected
    class var FNullObject: TMethode;
    class function CreateNullObject: TMethode;
    class function GetNullObject: TMethode;
  public
    class property NullObject: TMethode read GetNullObject;
  private
    FNo: Integer;
    FName: String;
  protected
    procedure SetNo(AValue: Integer); virtual;
    procedure SetName(const AValue: string); virtual;
  public
    constructor Create;
    destructor Destroy; override;
    function IsNullObject: Boolean;
    property No: Integer read FNo write SetNo;
    property Name: String read FName write SetName;
  end;

  TAnalyse = class
  private
    FNo: Integer;
    FName: String;
    FMethode : TMethode;
    function GetMethode: TMethode;
    procedure SetMethode(AValue: TMethode);
  public
    constructor Create;
    destructor Destroy; override;
    property No: Integer read FNo write FNo;
    property Name: String read FName write FName;
    property Methode: TMethode read GetMethode write SetMethode;
  end;

implementation

class function TMethode.CreateNullObject: TMethode;
begin
  Result := TMethode.Create;
end;

class function TMethode.GetNullObject: TMethode;
begin
  if not Assigned(FNullObject) then
    FNullObject := CreateNullObject;

  Result := FNullObject;
end;

procedure TMethode.SetNo(AValue: Integer);
begin
  if IsNullObject then
    Exit;

  FNo := AValue;
end;

procedure TMethode.SetName(const AValue: string);
begin
  if IsNullObject then
    Exit;

  FName := AValue;
end;

function TMethode.IsNullObject: Boolean;
begin
  Result := (Self = FNullObject);
end;

destructor TMethode.Destroy;
begin
  if IsNullObject then
    FNullObject := nil;

  inherited;
end;

function TAnalyse.GetMethode: TMethode;
begin
  if Assigned(FMethode) then
    Result := FMethode
  else
    Result := TMethode.NullObject;
end;

procedure TAnalyse.SetMethode(AValue: TMethode);
begin
  if AValue.IsNullObject then
    FMethode := nil
  else
    FMethode := AValue;
end;

finalization
  TMethode.FNullObject.Free; // oder im class-destructor

end.

Geändert von Blup ( 2. Aug 2017 um 13:24 Uhr) Grund: GetMethode korrigiert, Hilfsklasse für Nullobjekt eingespart
  Mit Zitat antworten Zitat
Wosi

Registriert seit: 29. Aug 2007
59 Beiträge
 
#12

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 11:51
Eine ganz andere Frage:

destructor Destroy; reintroduce;
Die wurde hier im Hause auch schon diskutiert. Der, der diese Klassen definiert hat, meint es sei nötig.
Ich wette er liegt falsch.
Destroy wird von TObject.Free aufgerufen und ist virtual. Mit reintroduce wird der Aufruf des neu definierten Destruktors verhindert.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#13

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 12:11
Und dieser neue Destructor wird ausschlichlich nur dann aufgerufen, wenn die Variable diesen Klassentyp hat, bzw. gecastet wird.

Free und Destroy über Variable/Cast eines Vorfahren ignoriert dieses Destroy dann, was ja eigentlich fast nie gewollt sein dürfte.
Wenn doch, dann benennt diesen neuen Destructor doch bitte anders.


PS: Post #11, da fehlt der Vorfahre beim NullObject.

Ableitung mit böser Prüfung im Vorfahren.
Delphi-Quellcode:
type
  TMethode = class
    ...
    function IsNullObject: Boolean; {virtual;}
  end;

  TMethodeNullObject = class(TMethodeNullObject);

function TMethode.IsNullObject: Boolean;
begin
  Result := Self is TMethodeNullObject;
end;
oder ohne Ableitung
Delphi-Quellcode:
type
  TMethode = class
    ...
    function IsNullObject: Boolean; {virtual;}
  end;

function TMethode.IsNullObject: Boolean;
begin
  Result := Self = FNullObject;
end;
$2B or not $2B

Geändert von himitsu ( 2. Aug 2017 um 12:17 Uhr)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#14

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 12:34

Ginge statt diesem auch ein Marker-Interface (so kenne ich es in Java)?

Delphi-Quellcode:
type
  TMethode = class
    ...
    function IsNullObject: Boolean; {virtual;}
  end;

  TMethodeNullObject = class(TMethodeNullObject);

function TMethode.IsNullObject: Boolean;
begin
  Result := Self is TMethodeNullObject;
end;
oder ohne Ableitung
Delphi-Quellcode:
type
  TMethode = class
    ...
    function IsNullObject: Boolean; {virtual;}
  end;

function TMethode.IsNullObject: Boolean;
begin
  Result := Self = FNullObject;
end;
Z.B.

Delphi-Quellcode:
type
  INullObject = interface
[GUID]
end;

TMethodeNullObject = class(TMethodeNullObject, INullObject);


und testen dann mit

Supports(FNullObject, INullObject);
Dadurch spart man das Deklarieren klassenspezifischer Nullobjektklassen.
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
505 Beiträge
 
Delphi 12 Athens
 
#15

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 12:44
Ich denke das
function TAnalyse.GetMethode: TMethode;
begin
if Assigned(FAnalyse) then
Result := FAnalyse
else
Result := TAnalyse.NullObject;
end;
[/delphi]
müsste
Delphi-Quellcode:
function TAnalyse.GetMethode: TMethode;
begin
  if Assigned(FMethode) then
    Result := FMethode
  else
    Result := TMethode.NullObject;
end;
heissen.

Ich verstehe allerdings nicht ganz, warum damit der Zugriff Label1.Caption := Analyse.Methode.Name funktionieren sollte. Der Lesezugriff auf FName erfolgt ja immer noch direkt, d.h. ohne Getter und darin enthaltener Prüfung auf IsNullObject.

Nachteil ist, dass alle Properties über Set/Get erfolgen müssen. Da erscheint ein Dummy einfacher.
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#16

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 13:14
Hab eure Anregungen und Fehlerhinweise berücksichtigt. War aus dem Stehgreif ohne Entwicklungsumgebung, da kann man sich mal vertippen.

@norweger60
Analyse.Methode liefert üer den Getter nun bei FMethode = nil das Nullobjekt zurück. Der Name ist zwar leer, aber das macht ja bei einem Label auch Sinn. Sollte ein Fehler auftreten, der Schreibzugriffe auf Properties des Nullobjekt zur Folge hat, werden diese ignoriert. So wird der Fehler nicht in andere Programmteile verschleppt.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#17

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 13:19
Delphi-Quellcode:
type
  TMethodeNullObject = class(TMethodeNullObject, INullObject);
Dadurch spart man das Deklarieren klassenspezifischer Nullobjektklassen.
Die Klasse gibt es dennoch, aber so hätte man eine gemeinsame Prüfmethode für mehrere Klassen.

Wenn man alle NullObjekte in einen gemeinsamen Store (Liste) legt, dann könnte man auch sagen "NullObjekt ist das, was in der Liste ist" und braucht dann nur eine Objektklasse.
$2B or not $2B
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
505 Beiträge
 
Delphi 12 Athens
 
#18

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 14:06
@norweger60
Analyse.Methode liefert üer den Getter nun bei FMethode = nil das Nullobjekt zurück. Der Name ist zwar leer, aber das macht ja bei einem Label auch Sinn. Sollte ein Fehler auftreten, der Schreibzugriffe auf Properties des Nullobjekt zur Folge hat, werden diese ignoriert. So wird der Fehler nicht in andere Programmteile verschleppt.
Analyse.Methode liefert ja auch NIL zurück, wenn ich sie gar nicht belegt habe. Und NIL.Name führt dann zur Exception. Oder überseh ich was?

Geändert von norwegen60 ( 2. Aug 2017 um 14:35 Uhr)
  Mit Zitat antworten Zitat
bra

Registriert seit: 20. Jan 2015
711 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#19

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 14:32
Der vermutlich auch nicht funktioniert, wenn Analyse.Methode NIL ist.
Stimmt, da bin ich auch schonmal drüber gestolpert
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#20

AW: Zugriff auf Unterklasse absichern

  Alt 2. Aug 2017, 14:58
Es gibt bei Delphi die IfThen-Funktion, die ähnlich wie der Elvis-Operator (kannte die Bezeichnung bisher gar nicht) arbeitet.

Label1.Caption := IfThen(Assigned(Analyse.Methode), Analyse.Methode.Name, '');
Ist aber kein wirklich schöner Code.
Der vermutlich auch nicht funktioniert, wenn Analyse.Methode NIL ist.
Richtig - Er würde ja erst alle Parameter auswerten (und scheitern) bevor er diese komische IfThen -Methode überhaupt betreten würde.
Verstehe ich hier etwas falsch und IfThen soll nicht den ternären Operator simulieren? Wenn ich richtig liege, würde nämlich nur Assigned(Analyse.Method) ausgewertet - was ja vollkommen legitim ist - und dann abhängig vom Ergebnis das erste- oder zweite Argument zurückgegeben.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 23:06 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