AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Override von Konstanten im Objekt - Alternative?
Thema durchsuchen
Ansicht
Themen-Optionen

Override von Konstanten im Objekt - Alternative?

Ein Thema von bernau · begonnen am 25. Dez 2017 · letzter Beitrag vom 30. Dez 2017
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.295 Beiträge
 
Delphi 12 Athens
 
#1

Override von Konstanten im Objekt - Alternative?

  Alt 25. Dez 2017, 16:59
Delphi-Version: 10 Berlin
Ich erkläre mal kurz, was ich möchte, was aber nicht funktioniert

Ich habe ein Basisobjekt (TObjectA). Dort ist eine Konstante definiert. Eine Procedure macht irgendetwas damit.

Ich leite von TObjectA das TObjectB ab. Unterschied ist, daß die Konstante einen anderen Wert hat.

Delphi-Quellcode:
  TObjectA = class
  private
    const
    cTestValue = 'aaa';
  public
    Procedure MachWasMitTestValue;
  end;

  TObjectB = class(TObjectA)
  private
    const
    cTestValue = 'bbb';
  public
  end;
Problem ist natürlich, dass für die "Procedure MachWasMitTestValue" cTestValue immer den Wert 'aaa' besitzt. Auch wenn ich TObjectB instanziere und dort diese Funktion aufrufe.

Die Alternative:

Ich Erzeuge eine virtuelle Funktion im TObjectA und überschreibe diese im TObjectB

Delphi-Quellcode:
Type
  TObjectA = class
  public
    Function testvalue: String; virtual;
    Procedure MachWasMitTestValue;
  end;

  TObjectB = class(TObjectA)
  public
    Function testvalue: String; override;
  end;

  function TObjectA.testvalue: String;
  begin
    Result := 'aaa';
  end;

  function TObjectA.testvalue: String;
  begin
    Result := 'bbb';
  end;
Der Nachteil ist für mich, dass die Werte für TestValue in der Implementation stehen. Ich möchte diese Werte aber direkt in der Deklaration des Objects sehen.

Dann habe ich noch an Properties mit einem Default-Wert gedacht. Damit geht es aber nur mit ordinalen Tpyen. Einen Defaultwert für einen String kann man nicht angeben.

Hat jeman eine Idee, wie ich die Werte in der Deklaration des Objektes festlegen kann und diese trotzdem Virtuell sind, damit die "Procedure MachWasMitTestValue" trotzdem auf die Werte des Kindobjektes zugreifen kann?

Vieleicht Attribute? Kenne ich mich aber nicht mit aus.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#2

AW: Override von Konstanten im Objekt - Alternative?

  Alt 25. Dez 2017, 17:20
Kombinier doch einfach beide Ansätze:
Delphi-Quellcode:
Type
  TObjectA = class
  strict private const
    cTestValue = 'aaa';
  public
    Function testvalue: String; virtual;
    Procedure MachWasMitTestValue;
  end;

  TObjectB = class(TObjectA)
  strict private const
    cTestValue = 'bbb';
  public
    Function testvalue: String; override;
  end;

  function TObjectA.testvalue: String;
  begin
    Result := cTestValue;
  end;

  function TObjectB.testvalue: String;
  begin
    Result := cTestValue;
  end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.295 Beiträge
 
Delphi 12 Athens
 
#3

AW: Override von Konstanten im Objekt - Alternative?

  Alt 25. Dez 2017, 17:27
Da habe ich auch schon dran gedacht.

Wobei das natürlich unnötigen Code erzeugt. Im Beispiel nicht ist es viel. Aber es ist ja nur ein Beispiel. Da sollen zukünftig mehrere abgeleitete Objekte vorkommen und mehrere Konstanten im Objekt. Das macht den Code unübersichtlich.

Aber danke für die Idee!
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
419 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Override von Konstanten im Objekt - Alternative?

  Alt 26. Dez 2017, 10:48
warum kann ich die Methode MachwasmitTestvalue auch nach der Freigabe von ObjectA aufrufen?
Delphi-Quellcode:
procedure TForm1.btn1Click(Sender: TObject);
var ObjectA:TObjectA;
begin
  ObjectA := TObjectA.Create;
  try
    lblA.Caption:=ObjectA.testvalue;
    //ObjectA.MachWasMitTestValue;
  finally
    ObjectA.Free;
  end;
  ObjectA.MachWasMitTestValue;
end;
eigentlich gehört sie doch in den try... finaly-Abschnitt, wie auskommentiert dargestellt.
Norbert
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.295 Beiträge
 
Delphi 12 Athens
 
#5

AW: Override von Konstanten im Objekt - Alternative?

  Alt 26. Dez 2017, 11:12
warum kann ich die Methode MachwasmitTestvalue auch nach der Freigabe von ObjectA aufrufen?
Delphi-Quellcode:
procedure TForm1.btn1Click(Sender: TObject);
var ObjectA:TObjectA;
begin
  ObjectA := TObjectA.Create;
  try
    lblA.Caption:=ObjectA.testvalue;
    //ObjectA.MachWasMitTestValue;
  finally
    ObjectA.Free;
  end;
  ObjectA.MachWasMitTestValue;
end;
eigentlich gehört sie doch in den try... finaly-Abschnitt, wie auskommentiert dargestellt.
Ähm. Deinen Post verstehe ich nicht. Ist der Code von dir, oder von einem ggf. gelöschten Post?

Natürlich gehört die Anweisung in den Try...finally Block und muss aufgerufen werden bevor das Objekt wieder freigegeben wird.

Wenn es doch funktioniert, ist es Zufall, weil der Speicherbereich, in dem sich das instanzierte Objekt befunden hatte, noch nicht überschrieben wurde.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
419 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

AW: Override von Konstanten im Objekt - Alternative?

  Alt 26. Dez 2017, 11:21
ich habe einfach mit dem Beispiel von Uwe Rabe gespielt und folgenden code vervollständigt:
Delphi-Quellcode:
unit uMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    lblA: TLabel;
    lblB: TLabel;
    btn1: TButton;
    btn2: TButton;
    btn3: TButton;
    procedure btn1Click(Sender: TObject);
    procedure btn3Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Type
  TObjectA = class
  strict private const
    cTestValue = 'aaa';
  public
    Function testvalue: String; virtual;
    Procedure MachWasMitTestValue;
  end;

  TObjectB = class(TObjectA)
  strict private const
    cTestValue = 'bbb';
  public
    Function testvalue: String; override;
  end;

procedure TObjectA.MachWasMitTestValue;
begin
  ShowMessage(testvalue);
end;

function TObjectA.testvalue: String;
  begin
    Result := cTestValue;
  end;

  function TObjectB.testvalue: String;
  begin
    Result := cTestValue;
  end;

procedure TForm1.btn1Click(Sender: TObject);
var ObjectA:TObjectA;
begin
  ObjectA := TObjectA.Create;
  try
    lblA.Caption:=ObjectA.testvalue;
    //ObjectA.MachWasMitTestValue;
  finally
    ObjectA.Free;
  end;
  ObjectA.MachWasMitTestValue;
end;

procedure TForm1.btn2Click(Sender: TObject);
var ObjectB: TObjectB;
begin
  ObjectB:=TObjectB.create;
  try
    lblB.Caption:=ObjectB.testvalue;
    ObjectB.MachWasMitTestValue;
  finally
    ObjectB.free;
  end;
end;

procedure TForm1.btn3Click(Sender: TObject);
begin
  close;
end;

end.
Dann habe ich wie geschrieben die Methode MachwasmitTestValue versehentlich nach der Freigabe des ObjectA aufgerufen und es geht. Es geht wie es gehen soll innerhalb des try...finaly-Blocks, aber ach Wunder: auch hinter diesem, aber warum?
Norbert
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Override von Konstanten im Objekt - Alternative?

  Alt 26. Dez 2017, 11:39
Es geht wie es gehen soll innerhalb des try...finaly-Blocks, aber ach Wunder: auch hinter diesem, aber warum?
Das ist als würde man fragen warum es immer klappt wenn man bei grün über die Ampel fährt, aber es die letzten beiden male auch keinen Zusammenprall gab als man bei rot drüber fuhr. Das Freigeben eines Objekts löscht seine Daten nicht zwangsläufig aus dem Speicher. Es gibt sie "zur weiteren Verwendung frei". Es kann klappen. Schreibst du deine Prozedur ein wenig anders klappt es vielleicht schon nicht mehr.

Lange Rede, kurzer Sinn: Tu es nicht
  Mit Zitat antworten Zitat
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
419 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: Override von Konstanten im Objekt - Alternative?

  Alt 26. Dez 2017, 11:48
na gut, Ich fahre also immer ordentlich über die Kreuzung. War ja nur mal so ein Gespiele mit dem Beispiel. Danke
Norbert
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.202 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Override von Konstanten im Objekt - Alternative?

  Alt 26. Dez 2017, 11:54
Bau mal in deinem Testprogramm FastMM4 (https://github.com/pleriche/FastMM4) bzw. aktiviere über Compilerdefines die Checks in dem in Delphi (abgespeckten) FastMM4.
Dann wird entsprechend Meckern das du versuchst auf ein freigegebenes Objekt zuzugreifen.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
419 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: Override von Konstanten im Objekt - Alternative?

  Alt 26. Dez 2017, 13:58
Hallo Berndhard Geyer; Ich habe mir das Programm FastMM4 heruntergeladen und einen FastMMuseTracker in das Programm aufgenommen.(in der use-Anweisung der dpr wurde als erstes FastMMU aufgeführt):
Delphi-Quellcode:
procedure TForm1.btn4Click(Sender: TObject);
begin
  ShowFastMMUsageTracker;
end;
rufe dann im Programm zunächst den FastMMUUsageTracker auf und dann immer wieder die "falsche Methode"
Delphi-Quellcode:
var ObjectA:TObjectA;
begin
  ObjectA := TObjectA.Create;
  try
    lblA.Caption:=ObjectA.testvalue;
    //ObjectA.MachWasMitTestValue;
  finally
    ObjectA.Free;
  end;
  ObjectA.MachWasMitTestValue;
end;
er läßt mich immer wieder bei "ROT" über die Strasse und nie kommt ein Auto oder ein Polizist. Aus den Anzeigen im Tracker werde ich nicht schlau, ob und wann er mir eine Warnung gibt.
Ich will bitte keine Haupt- und Staatsaktion aus dieser Spielerei machen. Mir ist durchaus klar, dass der Methodenaufruf an dieser Stelle falsch ist, doch warum erhalte ich keine Warnung. Wo könnte ich evtl. eine Änderung dazu einbauen?
Norbert

Geändert von EdAdvokat (26. Dez 2017 um 14:05 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 00:12 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