AGB  ·  Datenschutz  ·  Impressum  







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

Constructor verbergen

Ein Thema von s-off · begonnen am 30. Jan 2008 · letzter Beitrag vom 30. Jan 2008
Antwort Antwort
s-off
(Gast)

n/a Beiträge
 
#1

Constructor verbergen

  Alt 30. Jan 2008, 09:30
Hallo zusammen,

folgende Ausgangssituation:

Gegeben sind die folgenden Klassen (abgespeckte Darstellung):
Delphi-Quellcode:
TMeinMemoObject = Class(TObject)
private
  FValue: String;
public
  Constructor Create(oMemo: TMeinMemo);

  Property Value: String read FValue;
end;

TMeinMemo = Class(TMemo)
private
  Function GetMeinMemoObject: TMeinMemoObject;
public
  Property MeinMemoObject : TMeinMemoObject read GetMeinMemoObject;
end;
Objekte der Klasse 'TMeinMemo' können direkt Objekte vom Typ 'TMeinMemoObject' erzeugen.
Zugriff erfolgt dann über die entsprechende Property, bspw.
sMeinString := oMeinMemo.MeinMemoObject.Value; So, wie ich nun aber auf das Feld 'Value' zugreifen kann, wäre es genauso möglich, auf den Constructor zuzugreifen:
oMeinMemo.MeinMemoObject.Create(oMeinMemo); Und genau das möchte ich verhindern.
Im Klartext: ich möchte verhindern, dass ein Objekt der Klasse 'TMeinMemoObject' von außen erzeugt werden kann.

Nun dachte ich, dass es genügen würde, den Constructor aus dem Public- einfach in den Private-Bereich zu packen.
Leider genügt das nicht, da so ja immer noch der Constructor von der Vorfahrklasse 'TObject' aufrufbar ist.

Meine Frage nun: Wie kann ich jeglichen Zugriff auf den Constructor von 'TMeinMemoObject' von außen verhindern, und diesen nur der Klasse 'TMeinMemo' ermöglichen?
  Mit Zitat antworten Zitat
Benutzerbild von RavenIV
RavenIV

Registriert seit: 12. Jan 2005
Ort: Waldshut-Tiengen
2.875 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: Constructor verbergen

  Alt 30. Jan 2008, 09:48
Also ich würde versuchen, den Constructor von TObject zu überschreiben und dann aus public rausnehmen.
Kann sein, dass Du dann eine Warning bekommst, aber auch das kann man bestimmt irgendwie "reparieren".
Ausnahmsweise kann man die Warning auch ignorieren.
Klaus E.
Linux - das längste Text-Adventure aller Zeiten...
Wer nie Linux mit dem vi konfiguriert hat, der hat am Leben vorbei geklickt.
  Mit Zitat antworten Zitat
TBx
(Administrator)

Registriert seit: 13. Jul 2005
Ort: Stadthagen
1.893 Beiträge
 
Delphi 12 Athens
 
#3

Re: Constructor verbergen

  Alt 30. Jan 2008, 09:53
Den Constructor kannst Du über strict private sperren.
Diesen kannst Du dann über eine private Function Aufrufen. Diese private Function ist von Klassen aus, die in der selben Unit definiert sind, aufrufbar.

Das Prinzip kannst Du Dir angucken, wenn Du mal nach Singleton suchst, da wird auch der Constructor gesperrt.

Gruß

onlinekater
Thomas Breitkreuz
Gruß Thomas
- Admin DelphiPRAXIS
- Admin Delphi-Treff
- Embarcadero MVP
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#4

Re: Constructor verbergen

  Alt 30. Jan 2008, 10:21
Hallo,
Zitat von RavenIV:
Also ich würde versuchen, den Constructor von TObject zu überschreiben und dann aus public rausnehmen.
Du weisst aber schon, dass man Sichtbarkeit nur erhöhen kann, aber niemals vermindern, oder?

sMeinString := oMeinMemo.MeinMemoObject.Value; Damit erzeugst Du IMHO kein neues Objekt, sondern rufst den Konstruktor eines bestehenden Objekts als normale Methode auf.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
s-off
(Gast)

n/a Beiträge
 
#5

Re: Constructor verbergen

  Alt 30. Jan 2008, 10:31
Hallo,

vielen Dank für Eure Tipps.

Bezüglich der 'strict private'-Variante habe ich es nun auf zweierlei Art und Weise probiert:
Delphi-Quellcode:
TMeinMemoObject = Class(TObject)
strict private
  Constructor Create; overload;
private
  FValue: String;
  
  Procedure CreateMeinMemoObject(oMemo: TMeinMemo);
public
  Property Value: String read FValue;
end;

TMeinMemo = Class(TMemo)
private
  Function GetMeinMemoObject: TMeinMemoObject;
public
  Property MeinMemoObject : TMeinMemoObject read GetMeinMemoObject;
end;
Aufruf dann per
Delphi-Quellcode:
Procedure TMeinMemo.BaueMemoObject;
var
  oMemoObject: TMeinMemoObject;
Begin
  oMemoObject := TMeinMemoObject.CreateMeinMemoObject(Self);
End;
Diese Variante hat mehrere Compilermeldungen zur Folge:
Zitat:
[Pascal Fehler] uMeinMemo.pas(563): E2076 Diese Form des Methodenaufrufs ist nur für Klassenmethoden erlaubt
[Pascal Fehler] uMeinMemo.pas(731): E2075 Diese Form des Methodenaufrufs ist nur in Methoden von abgeleiteten Typen erlaubt
Die zweite Variante sieht so aus:
Delphi-Quellcode:
TMeinMemoObject = Class(TObject)
strict private
  Constructor Create; overload;
private
  FValue: String;
protected
  Constructor Create(oMemo: TMeinMemo); overload;
public
  Property Value: String read FValue;
end;

TMeinMemo = Class(TMemo)
private
  Function GetMeinMemoObject: TMeinMemoObject;
public
  Property MeinMemoObject : TMeinMemoObject read GetMeinMemoObject;
end;
Aufruf dann per
Delphi-Quellcode:
Procedure TMeinMemo.BaueMemoObject;
var
  oMemoObject: TMeinMemoObject;
Begin
  oMemoObject := TMeinMemoObject.Create(Self);
End;
Diese Variante hat nur einen Hinweis zur Folge, der nicht weiter stört
Zitat:
[Pascal Hinweis] uTSplitCellStringGrid.pas(96): H2219 Das private-Symbol 'Create' wurde deklariert, aber nie verwendet
Alles weitere Funktioniert so weit.
Wenn ich nun aber versuche, von außen auf den Constructor zuzugreifen, dann wird mir dieser auch nicht mehr in der CodeVervollständigung angezeigt, aufrufen kann ich ihn aber trotzdem, was dann zu einer Exception führt

Wo liegt der Fehler?

Edit:
@xaromz
Zitat von xaromz:
sMeinString := oMeinMemo.MeinMemoObject.Value; Damit erzeugst Du IMHO kein neues Objekt, sondern rufst den Konstruktor eines bestehenden Objekts als normale Methode auf.
damit möchte ich ja auch gar kein neues Objekt erzeugen, sondern nur Zeigen, wie ich auf Felder dieser Klasse von außen zugreife - das Beispiel mit dem Erzeugen des Objektes war etwas weiter unten
Zitat:
oMeinMemo.MeinMemoObject.Create(oMeinMemo);
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#6

Re: Constructor verbergen

  Alt 30. Jan 2008, 10:43
Hallo,

Zitat von s-off:
@xaromz
Zitat von xaromz:
sMeinString := oMeinMemo.MeinMemoObject.Value; Damit erzeugst Du IMHO kein neues Objekt, sondern rufst den Konstruktor eines bestehenden Objekts als normale Methode auf.
damit möchte ich ja auch gar kein neues Objekt erzeugen, sondern nur Zeigen, wie ich auf Felder dieser Klasse von außen zugreife - das Beispiel mit dem Erzeugen des Objektes war etwas weiter unten
Zitat:
oMeinMemo.MeinMemoObject.Create(oMeinMemo);
upps , falsche Stelle zitiert. Also nochmal:
oMeinMemo.MeinMemoObject.Create(oMeinMemo); Damit erzeugst Du IMHO kein neues Objekt, sondern rufst den Konstruktor eines bestehenden Objekts als normale Methode auf.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Constructor verbergen

  Alt 30. Jan 2008, 10:44
Ich glaube nicht, dass das "sauber" geht. IMHO ist die beste Lösung (a.k.a das geringste Übel ), den "gewollten" Konstruktor privat zu machen sowie den unerwünschten geerbten zu überschreiben und als Implementierung eine Exception zu schmeißen. Damit kriegst du zwar leider keinen Compilerfehler bei unerlaubter Benutzung, aber immerhin einen deutlichen Hinweis zur Laufzeit.
Uli Gerhardt
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Constructor verbergen

  Alt 30. Jan 2008, 10:52
Selbst wenn du den Constructor verbergen kannst bringt dir das überhaupt nichts. Der Constructor ist nichts anderes als eine normale Methode die beim Aufruf als Klassen-Methode speicher anfordert. Wenn du dir aber zum Beispiel mit Application.CreateForm anschaust wirst du sehen das man nicht unbedingt den Constructor als Klassenmethode aufrufen muss um Speicher anzufordern.
Zudem kann man auch einfach immer auf einen Vorgänger casten wo der Constructor sichtbar ist und da den Constructor aufrufen.

Der Sinn ist also gleich null von dem was du vor hast. Und wenn du dir mal die Objecte der VCL anschaust wirst du auch nirgends sowas finden obwohl da genau das gleiche mit den Klassengemacht wird wie bei dir (ListView.Items.Add zum Beispiel).
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
s-off
(Gast)

n/a Beiträge
 
#9

Re: Constructor verbergen

  Alt 30. Jan 2008, 11:04
@xaromz:
Ups, bin schon ganz tüddelig
Meinte natürlich etwas wie
Delphi-Quellcode:
Procedure TForm1.TestClick(Sender: TObject);
Var
   oMeinMemoObject: TMeinMemoObject;
Begin
   oMeinMemoObject := TMeinMemoObject.Create(oMeinMemo);
End;
Zitat von uligerhardt:
Damit kriegst du zwar leider keinen Compilerfehler bei unerlaubter Benutzung, aber immerhin einen deutlichen Hinweis zur Laufzeit.
Ich glaube nicht, dass ich das möchte

@SirThornberry
Ok, überzeugt - ich lasse es, wie es ist.
Prinzipiell ist es ja auch nicht tragisch, da einfach nichts passiert, wenn der Constructor von außen aufgerufen wird.

Danke an alle.
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#10

Re: Constructor verbergen

  Alt 30. Jan 2008, 11:27
Zitat von s-off:
Zitat von uligerhardt:
Damit kriegst du zwar leider keinen Compilerfehler bei unerlaubter Benutzung, aber immerhin einen deutlichen Hinweis zur Laufzeit.
Ich glaube nicht, dass ich das möchte
Das glaub ich dir gern - geht mir nämlich genauso.
Aber Sicherheit zur Compilezeit kriegst du bei dem Thema mit Delphi AFAICS nicht.
Uli Gerhardt
  Mit Zitat antworten Zitat
Antwort Antwort


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 13:55 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