Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Verhindern von Instanzierung eines Objekts mit Create (https://www.delphipraxis.net/112610-verhindern-von-instanzierung-eines-objekts-mit-create.html)

warheart 24. Apr 2008 10:35


Verhindern von Instanzierung eines Objekts mit Create
 
Hallo Delphi Gemeinde

Meine erste Frage hier dreht sich um einen relativ komischen Wunsch, nicht so alltäglich.

Ich habe eine Klasse gemacht, die alle Methoden static hat und alle Membervariablen mit class var deklariert hat. Das Ganze ist nach diesem Beispiel von http://dn.codegear.com/article/34324 aufgebaut:
Delphi-Quellcode:
type
  TMyClass = class
    strict private
      class var
        FX: Integer;
    strict protected

    // Note: accessors for class properties must be declared class static.

      class function GetX: Integer; static;
     class procedure SetX(val: Integer); static;
    public
      class property X: Integer read GetX write SetX;
     class procedure StatProc(s: String); static;
  end;

TMyClass.X := 17;
TMyClass.StatProc('Hello');
Nun ist es allerdings immer noch möglich, den Constructor mit Create aufzurufen. Um allen potenziellen Benutzern der Klasse klar zu machen, dass man davon keine eigenen Instanzen machen darf, möchte ich das aufrufen von Create verbieten. Ist das irgendwie möglich? :gruebel:

Beispiel
Delphi-Quellcode:
TMyClass.StatProc('Hello'); // soll funktionieren
myObj := TMyClass.Create; // soll nicht funktionieren
Danke und Gruss an die Welt

s-off 24. Apr 2008 10:37

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Hallo,

anscheinend geht soetwas nicht; hatte das Problem auch schonmal -> hier

Muetze1 24. Apr 2008 12:03

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Schmeiss einfach eine Exception im Konstruktor. Dann wird die Erstellung des Objektes abgebrochen und es ist wie gewünscht.

warheart 24. Apr 2008 12:46

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Das gefällt mir eben auch nicht. Ich möchte wenn schon einen Compiler-Fehler. Weil sonst vergisst plötzlich jemand die Exception ab zu fangen und zu behandeln. Dann gibts plötzlich unschöne Effekte...

Ich habe auch schon mit einem abstrakten Constructor probiert
Delphi-Quellcode:
Constructor Create; virtual; abstract
Das gibt aber eben auch eine Exception und nicht einen Compiler-Fehler.

Bernhard Geyer 24. Apr 2008 12:58

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von warheart
Das gefällt mir eben auch nicht. Ich möchte wenn schon einen Compiler-Fehler. Weil sonst vergisst plötzlich jemand die Exception ab zu fangen und zu behandeln. Dann gibts plötzlich unschöne Effekte...

Der Entwickler wird doch wohl schon mindestens 1 * seinen Code aufrufen.
Das Problem bei Delphi ist das die abstrakt-Definition nicht bei der Klassendefinition möglich ist sondern nur auf Methodenebene.

warheart 13. Mai 2008 09:47

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Naja, ich habe mich nun entschieden, das ganze anders zu lösen. Und zwar habe ich ein globales Objekt erstellt (wird für Logging verwendet). So kann ich auch sicher sein, dass es das Objekt nur einmal gibt.

Danke jedenfalls für die Kommentare. Gruss

phXql 13. Mai 2008 10:30

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Was passiert, wenn man einen privaten Konstruktor definiert?

// Edit: Ach vergesst es, grad den anderen Thread gesehen und gelesen.. Da wurde ja genau das versucht.

FAlter 27. Mai 2008 21:39

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Hi,

der Thread ist zwar schon etwas älter. aber irgendwie ist mir gerade dazu eine Idee gekommen:

Ein abstrakter Konstruktor kann nicht aufgerufen werden! Das gibt sogar ne Warnung (sowie Exception zur Laufzeit), und mit DDevExtensions wird ein Fehler zur Compilezeit draus ;)

Naja, aber ne bessere Idee hab ich dann doch nicht.

Mfg
FAlter

s-off 28. Mai 2008 07:28

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von FAlter
Ein abstrakter Konstruktor kann nicht aufgerufen werden! Das gibt sogar ne Warnung (sowie Exception zur Laufzeit), und mit DDevExtensions wird ein Fehler zur Compilezeit draus ;)

Hat wohl den gleichen Effekt wie 'strict private' :?

FAlter 28. Mai 2008 10:36

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,

ich dachte, es wurde eine Lösung gesucht, die nicht compiliert. Bitte, man muss nur Warnungen als Fehler interpretieren, und das geht mit Hier im Forum suchenDDevExtensions. Siehe Bild.

Mfg
FAlter

Meflin 28. Mai 2008 10:40

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von FAlter
ich dachte, es wurde eine Lösung gesucht, die nicht compiliert. Bitte, man muss nur Warnungen als Fehler interpretieren, und das geht mit Hier im Forum suchenDDevExtensions. Siehe Bild.

Das bringt ja wohl mal herzlich wenig - oder willst du mit deiner Unit auch gleich immernoch die DevExtensions mitliefern und den Benutzer außerdem dazu zwingen, diese Einstellung zu verwenden :gruebel:

idontwantaname 28. Mai 2008 10:53

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Bin mit Delphi nicht mehr so am laufenden, aber in C# kämen folgende Möglichkeiten in Frage:
  • privater Konstruktur - die Klasse kann noch erzeugt werden durch eine statische Methode der Klasse selbst.
  • Die Klasse als static definieren, was besagt, dass die Klasse nur statische Elemente beinhalten kann. Ob es ein Delphi-Äquivalent gibt, weiß ich nicht.
Lg oli

FAlter 28. Mai 2008 10:56

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Hi,

ich sagte ja, eine bessere Idee hab auch ich nicht. Aber wenn der User keine DDevExtensions hat, sieht er trotzdem die Warnung (nur eben als Warnung), und da steht drin, dass der Konstruktor selbst abstrakt ist. Ein guter Programmierer sieht sich die Warnungen auch mal an, und spätestens dann bemerkt er seien Fehler. Bei strict private kommt nicht einmal eine Warnung :( Jedenfalls bin ich der Ansicht, dass ein abstrakter Konstruktor deutlich besser ist als ein privater. Wer sicher gehen will, zwingt dem Programmierer eben komische Parameter auf.

Delphi-Quellcode:
type
  TTest = class
    constructor Create(var Do_Not_Call_This_Constructor: TTest); virtual; abstract;
  end;
Aber darauf würde ich sogar verzichten.

Mfg
FAlter

himitsu 28. Mai 2008 22:44

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Code:
type
  TMyClass = [color=#ff0000]record[/color]
    strict private
      class var
        FX: Integer;
    strict protected

    // Note: accessors for class properties must be declared class static.

      class function GetX: Integer; static;
     class procedure SetX(val: Integer); static;
    public
      class property X: Integer read GetX write SetX;
     class procedure StatProc(s: String); static;
  end;
Und wie wäre es in soeinem Fall garnicht erst eine Klasse zu verwenden?

ein Record hat Erstens keine Instanzen und Zweitens hat er in Delphi auch keinen Constructor.

bennixview 29. Mai 2008 11:47

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Was ist denn wenn man die Klasse selber als abstract deklariert ?!?!

Phoenix 29. Mai 2008 11:50

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Liest Du die oberen Beiträge?

Zitat:

Zitat von Bernhard Geyer
Das Problem bei Delphi ist das die abstrakt-Definition nicht bei der Klassendefinition möglich ist sondern nur auf Methodenebene.


bennixview 29. Mai 2008 11:52

Re: Verhindern von Instanzierung eines Objekts mit Create
 
class abstract

Classes, and not just methods, can be declared as abstract.

type
TAbstractClass = class abstract
procedure SomeProcedure;
end;

http://www.codegear.com/products/del...n32/whats-new/

Phoenix 29. Mai 2008 12:01

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Oh mann..

Das ist neu in Delphi 2007. Du hast wohl nicht geguckt, welche Delphi-Version der OP benutzt?

bennixview 29. Mai 2008 12:06

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Immer locker bleiben,

wollte ja nur aufzeigen dass es möglich ist.

s-off 29. Mai 2008 12:44

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von Phoenix
Das ist neu in Delphi 2007. Du hast wohl nicht geguckt, welche Delphi-Version der OP benutzt?

Da muss ich Dir widersprechen.

Die Überschrift sagt ganz eindeutig:
Zitat:

New and Enhanced IDE Features since Delphi 7
Das sagt wohl ganz klar aus, dass die Features mit Delphi 8, 2005, 2006 oder 2007 eingeführt worden sind, und nicht erst mit 2007.

Und in der Tat kann ich in Delphi 2006 eine als 'sealed' gekennzeichnete Klasse erstellen, die sich auch wirklich nicht ableiten lässt.

Nur 'abstract' muckt ein bissel rum.

[OT]
Desweiteren war Dein Umgangston gegenüber bennixview nicht gerade nett.
Nur mal so angemerkt, im Zuge der hiesigen Diskussionen zu den Themen 'Neue Leute', 'Jeder hat eine Chance', 'Reizbarkeit'...

Manchmal habe ich echt das Gefühl, dass hier einiges vertauscht wird.
Der, der helfen will, kriegt eins auf den Deckel, wenns mal falsch ist (was es hier definitiv nicht war), und die wirklichen Nervensägen kriegen Zucker in den Arsch geblasen.
[/OT]

Edit: da ich ja auch manchmal etwas überreizt bin und mit meinen Interpretationen daneben haue - sollte ich Deine Äußerungen falsch verstanden haben - sorry. Ansonsten - denk mal drüber nach.

Phoenix 29. Mai 2008 13:12

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von s-off
Das sagt wohl ganz klar aus, dass die Features mit Delphi 8, 2005, 2006 oder 2007 eingeführt worden sind, und nicht erst mit 2007.

Nein. In der Überschrift steht
Zitat:

Delphi 2007 for Win32 What's New
New and Enhanced IDE Features since Delphi 7
.
Dort sind - wie die Überschrift Aussagt - alle Features gelistet, die in 2007 neu sind. Und zwar kumuliert seit Delphi 7 (weil das die am meisten eingesetzte Delphi-Version ist.

Dass dort dann logischerweise auch wieder alte Features von Delphi 8, 2005 und 2006 drin stehen ist logisch, aber diese Liste ist so wie sie da steht nur Verbindlich für 2007.

So, und nun genug des Offtopic. Zum Rest folgt im Laufe des Tages ne PN.

s-off 29. Mai 2008 13:21

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von Phoenix
Zitat:

Zitat von s-off
Das sagt wohl ganz klar aus, dass die Features mit Delphi 8, 2005, 2006 oder 2007 eingeführt worden sind, und nicht erst mit 2007.

Nein. In der Überschrift steht
Zitat:

Delphi 2007 for Win32 What's New
New and Enhanced IDE Features since Delphi 7
.
Dort sind - wie die Überschrift Aussagt - alle Features gelistet, die in 2007 neu sind. Und zwar kumuliert seit Delphi 7 (weil das die am meisten eingesetzte Delphi-Version ist.

Dass dort dann logischerweise auch wieder alte Features von Delphi 8, 2005 und 2006 drin stehen ist logisch, aber diese Liste ist so wie sie da steht nur Verbindlich für 2007.

So, und nun genug des Offtopic. Zum Rest folgt im Laufe des Tages ne PN.

[OT]
Entschuldige bitte, aber willst Du mich für blöd verkaufen?
Du widersprichst Dir selber auf ganzer Linie:
Zitat:

Zitat von Phoenix
Dort sind - wie die Überschrift Aussagt - alle Features gelistet, die in 2007 neu sind.

Zitat:

Zitat von Phoenix
Dass dort dann logischerweise auch wieder alte Features von Delphi 8, 2005 und 2006 drin stehen ist logisch, aber diese Liste ist so wie sie da steht nur Verbindlich für 2007.

Natürlich ist die Liste ausschließlich für D2007 verbindlich. Ich habe auch nichts anderes behauptet.
Das ändert aber nichts an der Tatsache, dass eines dieser Features bereits in Delphi 8, 2005 und 2006 eingeführt worden sein kann, was bei 'abstract' wohl zutrifft, da es in D2006 verfügbar ist - und der OP hat D2006.

Also war Deine Aussage
Zitat:

Zitat von Phoenix
Das ist neu in Delphi 2007.

schlicht und einfach falsch!

Und spart Euch jeglichen Kommentar bzgl. dieses kleinen Ausrasters hier - aber wenn jemand meint, er müsse mich für doof verkaufen, nur wegen seiner scheinbaren Autorität als Moderator dieses Forums, dann platzt mir echt der Kragen.

Von mir aus könnt Ihr mich nun verwarenen, rausschmeißen, oder sonst was.
Aber so eine Nummer ziehst Du mit mir bitte nicht nochmal ab!

Und mir dann mit Hinweis auf OT noch verbieten wollen, mich dazu zu äußern...

Edit:
Und wenn Du jetzt meinst, diesen meinen Beitrag hier löschen zu müssen, dann stellst Du Dir selber ein Armutszeugnis aus.
[/OT]

Phoenix 29. Mai 2008 13:28

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Dann Probiere doch mal aus ob Dein 2006er Compiler verhindert, dass Du eine Instanz einer abstrakten Klasse erzeugen kannst. Wenn er das wie der 2007er auch verhindern würde, dann hättest Du recht, und dieses feature gäbe es schon in 2006.

Dieses Feature gibt es aber - wie Du schnell herausfinden wirst - erst in Delphi 2007.

Und jetzt erkläre mir bitte mal, wo ich Dich für Dumm verkaufe oder wo das schlicht und einfach falsch wäre.
Ich glaub, ich bin echt im falschen Film.

Edit: Und ich bin der Meinung, da wäre jetzt eine öffentliche Entschuldigung mehr als angebracht.

s-off 29. Mai 2008 13:39

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von Phoenix
Dann Probiere doch mal aus ob Dein 2006er Compiler verhindert, dass Du eine Instanz einer abstrakten Klasse erzeugen kannst. Wenn er das wie der 2007er auch verhindern würde, dann hättest Du recht, und dieses feature gäbe es schon in 2006.

Nein, das verhindert er nicht. Das sagte ich aber bereits oben schoneinmal.
Zitat:

Zitat von Phoenix
Nur 'abstract' muckt ein bissel rum.

Ich sagte aber auch,
Zitat:

Und in der Tat kann ich in Delphi 2006 eine als 'sealed' gekennzeichnete Klasse erstellen, die sich auch wirklich nicht ableiten lässt.
Und 'sealed' steht direkt unter 'abstract', so dass es laut Deiner Theorie wohl auch erst in 2007 zur Verfügung stehen dürfte.
Da nicht zu jedem Feature die Version angegeben ist, kann jeder von uns nur Vermutungen anstellen; es sei denn, man testet es.

Zitat:

Zitat von Phoenix
Und jetzt erkläre mir bitte mal, wo ich Dich für Dumm verkaufe oder wo das schlicht und einfach falsch wäre.
Ich glaub, ich bin echt im falschen Film.

Ich sagte, dass die Überschrift "New and Enhanced IDE Features since Delphi 7" nicht zwingend festlegt, dass alle in der Liste angegebenen Features erst mit Delphi 2007 eingeführt sind, sondern dass die Möglichkeit besteht, dass sie bereits mit Delphi 8, 2005 oder 2006 eingeführt sein können.

Und diese Aussage stellst Du als unwahr dar. Da es daran aber schlicht und einfach nichts dran zu rütteln gibt, was duch das 'sealed'-Beispiel auch belegt ist, komme ich mir von Dir verarscht vor - ganz einfach.

Zitat:

Zitat von Phoenix
Edit: Und ich bin der Meinung, da wäre jetzt eine öffentliche Entschuldigung mehr als angebracht.

Ja, aber nicht meinerseits - darfst es aber auch per PN machen. Ich leide nicht unter Profilneurose und benötige somit keine öffentliche Genugtuung.

Muetze1 29. Mai 2008 13:42

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von Phoenix
Dann Probiere doch mal aus ob Dein 2006er Compiler verhindert, dass Du eine Instanz einer abstrakten Klasse erzeugen kannst. Wenn er das wie der 2007er auch verhindern würde, dann hättest Du recht, und dieses feature gäbe es schon in 2006.

Eben schnell getestet auf BDS2007 und RAD2007: Das Abstract Schlüsselwort akzeptiert der Compiler auch schon bei BDS2006, aber es hat dort noch keine Auswirkungen. Die Instanziierung der Klasse und deren Ableitungen wird nicht verhindert, nichtmal eine Warnung/Hinweis wird ausgegeben. In Delphi 2007 ist dies aber denn richtig umgesetzt.

Phoenix 29. Mai 2008 13:49

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von s-off
Ich sagte, dass die Überschrift "New and Enhanced IDE Features since Delphi 7" nicht zwingend festlegt, dass alle in der Liste angegebenen Features erst mit Delphi 2007 eingeführt sind, sondern dass die Möglichkeit besteht, dass sie bereits mit Delphi 8, 2005 oder 2006 eingeführt sein können.

Und diese Aussage stellst Du als unwahr dar. Da es daran aber schlicht und einfach nichts dran zu rütteln gibt, was duch das 'sealed'-Beispiel auch belegt ist, komme ich mir von Dir verarscht vor - ganz einfach.

Zitiere bitte wo ich sage, dass keines dieser Featurs vor 2007 eingeführt wurde?
Soweit ich mich erinnere, habe ich gesagt, dass das eine kumulierte Liste seit Delphi 7 ist.
Und ich habe zudem gesagt, dass man abstrakte Klasse erst ab Delphi 2007 nicht mehr instanzieren kann.

Weder die eine, noch die andere Aussage ist falsch. Die erste deckt sich zudem noch mit Deiner.
Nochmal: Wieso kommst Du Dir dabei verarscht vor?

Du behauptest doch, ich hätte das Gegenteil von dem gesagt, wass da oben bei mir schwarz auf weiss stehst?

Ach.. mir wird das jetzt zu bunt. Soll sich jemand anderes aus dem Team oder Daniel darum kümmern.

peschai 29. Mai 2008 13:58

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Hallo,

@s-off und phoenix: Vertragt euch wieder und trinkt zusammen ein Bier :wink:

Wie ist den nun der Vorschlag von Himitsu mit dem "Record" anstelle "class" ?

FAlter 29. Mai 2008 14:09

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Hi,

Zitat:

Zitat von peschai
Wie ist den nun der Vorschlag von Himitsu mit dem "Record" anstelle "class" ?

Würde gehen, aber: Nur, so lange man nicht ableiten will. Ich wüsste nicht, dass man Records vererben kann.

Für diesen Thread hier (Klasse nur mit statischen Methoden) ist es also ok. Will man dagegen verhindern, dass eine Instanz einer abstrakten Basisklasse erstellt wird, so ist dies keine Lösung.


Mfg
FAlter

nicodex 30. Mai 2008 09:03

Re: Verhindern von Instanzierung eines Objekts mit Create
 
Zitat:

Zitat von FAlter
Würde gehen, aber: Nur, so lange man nicht ableiten will. Ich wüsste nicht, dass man Records vererben kann.

Für diesen Thread hier (Klasse nur mit statischen Methoden) ist es also ok. Will man dagegen verhindern, dass eine Instanz einer abstrakten Basisklasse erstellt wird, so ist dies keine Lösung.

Nun, da die zur Verfügung stehenden Sprachmittel für Klassen den Standardkonstruktor nicht verbergen können, wäre es vielleicht angebracht über ein anderes Design nachzudenken. Da alle Methoden statisch sind, kann ich nicht ganz nachvollziehen, warum es unbedingt eine Klasse sein muss - eine 'flache' Schnittstelle mittels Funktionen/Prozeduren hätte es auch getan. Wenn es denn unbedingt eine Klasse sein muss, dann erfüllt die angestrebte Logik das Muster eines Singletons - man könnte also ein Interface veröffentlichen und eine Funktion schreiben, die ein/das globales Objekt zurückgibt.

Für beide Lösungsansätze kann man jede Delphi-Version für Win32 verwenden, und muss sich nicht auf Delphi-Compiler beschränken, die 'class static' unterstützen.

Kurz: Ich halte die Fragestellung in diesem konkreten Fall für hinfällig, weil das Design an Compiler-Featuritis leidet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:30 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