Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Compiler Anweisung strict protected (https://www.delphipraxis.net/183884-compiler-anweisung-strict-protected.html)

ATS3788 11. Feb 2015 17:39

Compiler Anweisung strict protected
 
Hallo Freunde des großen Delphi

Ich bin bei dem Ribbon Interface von Bilsen
auf die
Compiler Anweisung strict protected
gestoßen. Was ist denn das schon wider.
Protected ist klar aber das "Strict".
Was ist der Unterschied ?

mkinzler 11. Feb 2015 17:44

AW: Compiler Anweisung strict protected
 
Das dies auch innerhalb einer Unit gilt.

Stevie 11. Feb 2015 17:51

AW: Compiler Anweisung strict protected
 
Normalerweise sind private und protected innerhalb derselben Unit nicht gültig. D.h. du kannst von außerhalb dieser Klasse auch auf die Member zugreifen. Der Zusatz strict setzt diese Sichtbarkeit auch innerhalb derselben Unit durch, was zu weniger verwobenem Code führen kann. Die Auswirkungen merkt man meist erst, wenn man mal 2 so verzahnte Klassen (beide greifen gegenseitig auf private und protected Member zu) in ihre eigenen Units verschieben möchte.

Kleiner Wermutstropfen, solltest du selber die Benutzung in Betracht ziehen - die Codevervollständigung kommt auch Jahre nach Einführung dieser keywords nicht so toll damit zurande. :(

klgid 11. Feb 2015 18:01

AW: Compiler Anweisung strict protected
 
Wie ich gerade vor Kurzem lernen musste, sind 'private' und 'protected' nur für die Sichtbarkeit (also sozusagen Vorschläge)
und können in abgeleiteten Objekten geändert werden.
"strict" sorgt dafür, dass sie funktionieren, wie man es aus anderen Sprachen kennt ...

DeddyH 11. Feb 2015 18:14

AW: Compiler Anweisung strict protected
 
Das stimmt so nicht ganz. Private-Member sind nur innerhalb der eigenen Klasse sichtbar, Protected-Member auch in abgeleiteten Klassen. Delphi hat diese Sichtbarkeiten aber aufgeweicht: stehen 2 Klassen innerhalb derselben Unit, so haben sie auch Zugriff auf private und protected Member der jeweils anderen Klasse, was dem Prinzip der Kapselung widerspricht. Probleme gibt es daher dann, wenn man diesen Umstand zunächst ausgenutzt, später die Klassen aber aus Gründen der Übersichtlichkeit auf verschiedene Units aufgeteilt hat. Daher wurde das "strict" eingeführt, was die Sichtbarkeiten im Sinne der Kapselung durchsetzt, so dass Klassen keinen Zugriff auf strict private und strict protected (es sei denn, es ist eine abgeleitete Klasse) mehr erhalten.

klgid 11. Feb 2015 18:41

AW: Compiler Anweisung strict protected
 
Genau das dachte ich auch.

Ich ging auch davon aus, dass das auch für abgeleitete Objekte gilt.
Leider musste ich mich in einer HandsOn-Experience auf unserem letzten DelpHHianer-Meeting eines besseren belehren lassen:

Klasse ClassA hat ein private Feld FFieldA.
Klasse ClassB wird - in einer gesonderten Unit - von ClassA abgeleitet und definiert FFieldA erneut, diesmal als public.
Damit greifen wir nunmehr public auf FFieldA von ClassA zu ...

Ich habe den Code selbst getippt, es stimmt wirklich.
Wenn ClassA allerdings FFieldA als STRICT private deklariert, funktioniert das nicht mehr.

Ach ja:
Helper Classes haben auch direkten Zugriff auf alles ...

himitsu 11. Feb 2015 18:57

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von klgid (Beitrag 1289551)
von ClassA abgeleitet und definiert FFieldA erneut

Feld = "Variable"?

Nein, dann wird die Sichtbarkeit nicht geändert, sondern zu hast zwei Felder, die zufällig gleich heißen.

Sir Rufo 11. Feb 2015 19:04

AW: Compiler Anweisung strict protected
 
Hier habe ich das mal erklärt
http://stackoverflow.com/questions/1...58763#16558763

himitsu 11. Feb 2015 19:07

AW: Compiler Anweisung strict protected
 
Und das Andere auch noch als Beispiel:
Delphi-Quellcode:
type
  TKlasseA = class
    FFeld: Integer;
  end;
  TKlasseB = class(TKlasseA)
    FFeld: Integer;
    constructor Create;
  end;

constructor TKlasseB.Create;
begin
  FFeld := 123;
  inherited FFeld := 456;
  ShowMessage(Format('%d %d', [FFeld, inherited FFeld]))
end;
Aber da aus unerfindlichen Gründen inherited nicht bei Feldern funktioniert, noch schnell ein Property oder Getter/Setter dazwischen.
Delphi-Quellcode:
type
  TKlasseA = class
    FFeld: Integer;
    property Feld: Integer read FFeld write FFeld;
  end;
  TKlasseB = class(TKlasseA)
    FFeld: Integer;
    property Feld: Integer read FFeld write FFeld;
    constructor Create;
  end;

constructor TKlasseB.Create;
begin
  Feld := 123;
  inherited Feld := 456;
  ShowMessage(Format('%d %d', [Feld, inherited Feld]))
end;
Und nun noch schnell aufrufen.
Delphi-Quellcode:
TKlasseB.Create.Free;
Aber da man Felder sowieso niemals öffentlich deklarieren sollte, sondern nur Private und in sonderfällen maximal Protected, ist das egal, denn die Sichbarkeit der Property, für den Zugriff darauf, kann man ja verschieben.

Der schöne Günther 11. Feb 2015 19:16

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von klgid (Beitrag 1289551)
Helper Classes haben auch direkten Zugriff auf alles ...

Dass Helferklassen auch auf private Attribute zugreifen können ist beabsichtigt. Ist anderswo zwar anders, aber ob das nun besser oder schlechter ist?

klgid 11. Feb 2015 19:19

AW: Compiler Anweisung strict protected
 
Dachte ich auch - und wurde enttäuscht :(
Ich habe das wirklich auf Diktat codiert und musste feststellen, dass Delphi (XE7) sich hier anders verhält als erwartet.
Wir (DelHHianer) nehmen an, dass dies ursprünglich so gedacht war, und später "strict" eingeführt wurde, um das erwartete Verhalten (wie bei Java u.a.) zu ermöglichen.

Ehrlich:
Ich wollte es auch nicht glauben!
Musste mich aber eines (Besseren?) Anderen belehren lassen.

Langer Rede, kurzer Sinn:
1. Wenn Ihr Eure Objektfelder privat halten wollt, verwendet STRICT PRIVATE!
2. Prüft noch einmal, worauf abgeleitete Objekte und Helfer Klassen zugreifen können ...

Inzwischen hat Sir Rufo auf einen Beitrag verwiesen.
Kurz überflogen stimmt der mit meiner ursprünglichen Sicht überein.

Versucht bitte einfach einmal, mein unten beschriebenes Szenario nachzuvollziehen - es funktioniert (leider) :(

Der schöne Günther 11. Feb 2015 19:54

AW: Compiler Anweisung strict protected
 
Ich verstehe das "leider" immer noch nicht.

private und protected heißt: "(Unterklassen und )selbe Unit"
Mit "strict" heißt es: "(Unterklassen)"

Und ein Klassenhelfer fühlt sich an keine Sichtbarkeitsmodifikatoren gebunden. Was ist denn daran jetzt so abenteuerlich?

Stevie 11. Feb 2015 20:02

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von klgid (Beitrag 1289559)
Ich habe das wirklich auf Diktat codiert und musste feststellen, dass Delphi (XE7) sich hier anders verhält als erwartet.

Versucht bitte einfach einmal, mein unten beschriebenes Szenario nachzuvollziehen - es funktioniert (leider) :(

Dann diktier uns mal den Code bitte - das glaube ich dir nämlich nicht - nix für ungut. ;)
Und wenn das so sein sollte, dann isses nen dicker Bock im Compiler.

Edit: Da, alles im grünen Bereich:
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Unit1 in 'Unit1.pas',
  Unit2 in 'Unit2.pas';

procedure Main;
var
  bar: TBar;
begin
  Writeln('TFoo.InstanceSize = ', TFoo.InstanceSize); // 12
  Writeln('TBar.InstanceSize = ', TBar.InstanceSize); // 16
  bar := TBar.Create;
  bar.fMyVar := 42;
  Writeln('bar.fMyVar = ', bar.fMyVar);              // 42
  Writeln('bar.MyVar = ', bar.MyVar);                // 0
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
Delphi-Quellcode:
unit Unit1;

interface

type
  TFoo = class
  private
    fMyVar: Integer;
  public
    property MyVar: Integer read fMyVar;
  end;

implementation

end.
Delphi-Quellcode:
unit Unit2;

interface

uses
  Unit1;

type
  TBar = class(TFoo)
  public
    fMyVar: Integer;
  end;

implementation

end.

mkinzler 11. Feb 2015 20:03

AW: Compiler Anweisung strict protected
 
Ohne strict it alles innerhalb der selben Unit public. Die Sichtbarkeit wirkt sich nur über Unitgrenzen aus. Mit strict erzwingt man das auch innerhalb der Unit.

klgid 11. Feb 2015 20:29

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1289564)
Ich verstehe das "leider" immer noch nicht.

private und protected heißt: "(Unterklassen und )selbe Unit"
Mit "strict" heißt es: "(Unterklassen)"

Und ein Klassenhelfer fühlt sich an keine Sichtbarkeitsmodifikatoren gebunden. Was ist denn daran jetzt so abenteuerlich?

Abenteuerlich ist daran, dass ich eine Berechnungsklasse schreibe und meine Berechnungsgrundlagen als PRIVATE markiere, damit mir niemand meine Berechnungen verändern kann, PRIVATE aber leider nicht UNVERÄNDERBAR bedeutet. STRICT PRIVATE tut dies dann ...

Diese Diskussion ist natürlich zu 99.9% philosophisch, d.h. es geht darum, inwieweit sich Delphi an anderen Sprachen orientiert.
"private" in JAVA ist PRIVATE, "private" in Delphi ist ...

Ich poste nachher noch entsprechenden Source - aktuell läuft auf meinem System gerade ein Update ...

Der schöne Günther 11. Feb 2015 21:47

AW: Compiler Anweisung strict protected
 
Gemessen an anderen vergleichbaren Sprachen sind die Sichtbarkeitsmodifikatoren in Delphi etwas... seltsam, ja. Aber neu und aufregend ist das ja eigentlich nicht, denn die waren ja schon immer so.

Ich bin ehrlich gesagt auch immer zu faul das "strict" mitzutippen. Im Endeffekt aber auch egal da mir andere Sprachen (z.B. Java) das "Pro Unit nur eine Klasse" mit Gewalt angewöhnt haben.

himitsu 11. Feb 2015 21:51

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von klgid (Beitrag 1289569)
PRIVATE aber leider nicht UNVERÄNDERBAR bedeutet. STRICT PRIVATE tut dies dann ...

Und dann kommt Einer daher und umgeht dennoch das PRIVATE wieder, indem er einen Class Helper oder die erweiterte RTTI benutzt,
wobei man die RTTI ordnungsgemäß und geziehlt deaktivieren könnte.

Aber gerade bei den Class Helpern versteh ich einfach nicht, warum das ist ist, denn im Prinzip sollte das eechtlich eher wie ein Nachfahre behandelt werden. :wall:

Sir Rufo 11. Feb 2015 22:37

AW: Compiler Anweisung strict protected
 
Das Gejammer hier ist ja kaum zum Aushalten :roll:

Über was regt ihr euch eigentlich auf? Dass ihr euch nicht umfassend informiert habt bzgl. dem
Delphi-Quellcode:
strict
? Oder überfordert es euch?

Da gibt man euch die Möglichkeit an die Hand die Zugriffe ganz fein zu steuern (quasi bis auf Nano-Ebene herunter) und ihr flennt hier rum, wie ein Kleinkind, dem man den Schnuller geklaut hat.

Ja, es ist richtig, dass man sich Gedanken machen muss ... (wie denken?!?) ... welche Zugriffe strikt untersagt werden müssen, unter allen Umständen.

Wo darf also kein
Delphi-Quellcode:
class helper
oder innerhalb der gleichen Unit - das ist ja nun eh lachhaft, wer Zugriff auf die Unit hat und an das Feld xy nicht dran kommt, der ändert einfach den Sourcecode, somit ist das da nur Selbstschutz, bzw. ein Statement "ich habe damals entschieden, da darf keiner sonst drauf zugreifen, denke nach warum" - irgendwas anderes darauf zugreifen, dann packt es einfach in den
Delphi-Quellcode:
strict private
.

Dafür wurde es geschaffen. Das ist die Intention. Genau wie es die Intention ist, dass
Delphi-Quellcode:
begin end
einen Code-Block bildet. Brauchst du es, benutze es, wenn nicht lass es. Wenn du es aber brauchen würdest, es aber nicht benutzt hast, was macht man dann? Ja man schreibt das dann einfach dort hin.

@himitsu

Der
Delphi-Quellcode:
class helper
wird wie ein Nachfahre in der gleichen Unit der gehelpten Klasse behandelt. Ansonsten käme der auch an den
Delphi-Quellcode:
strict private
Teil.

Soll ich euch noch was Nettes zeigen?
Delphi-Quellcode:
type
  TFoo = class
  strict private
    FValue : string;
  public
    procedure Bar( AFoo : TFoo );
    property Value : string read FValue;
  end;

procedure TFoo.Bar( AFoo : TFoo );
begin
  // beschreiben der strict private Variablen einer anderen Instanz
  AFoo.FValue := Self.FValue;
end;

Der schöne Günther 11. Feb 2015 22:58

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von Sir Rufo (Beitrag 1289580)
Delphi-Quellcode:
// beschreiben der strict private Variablen einer anderen Instanz

Spätestens hier ist Schluss! Das grenzt ja schon an Hausfriedensbruch. Ungeheuerlich dass hier noch keine gesetzlichen Regelungen existieren.

Sir Rufo 11. Feb 2015 23:29

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1289581)
Zitat:

Zitat von Sir Rufo (Beitrag 1289580)
Delphi-Quellcode:
// beschreiben der strict private Variablen einer anderen Instanz

Spätestens hier ist Schluss! Das grenzt ja schon an Hausfriedensbruch. Ungeheuerlich dass hier noch keine gesetzlichen Regelungen existieren.

Genau, denn derjenige, der diese Klasse konstruiert hat, den muss man ja jetzt davor schützen (äh, wovor eigentlich :gruebel:)

Bin ich eigentlich hier im Forum für betreutes Wohnen oder doch noch in einem Forum für Programmierer?

TiGü 12. Feb 2015 08:24

AW: Compiler Anweisung strict protected
 
:lol: Volle Zustimmung an Sir "Gunnery Sergeant" Rufo! :lol:

Daniel 12. Feb 2015 08:32

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von Sir Rufo (Beitrag 1289584)
Bin ich eigentlich hier im Forum für betreutes Wohnen oder doch noch in einem Forum für Programmierer?

Wir nennen es gern "betreutes Programmieren". ;-)
Dennoch muss auch ich zugeben, dass auch mir die Konsequenzen von "private" erst im Laufe von Jahren klar geworden sind. Als ich mit Delphi begonnen hatte, war mir das offen gestanden relativ schnurz. Da war das dann schon ein "aha"-Moment, als aus "private" plötzlich "strict private" wurde. Wenngleich ich es in realen Projekten eher weniger einsetze - vermutlich aus Gewohnheit und weil "private" in einem Atemzug mit "protected" und "public" schneller geschrieben ist.

DeddyH 12. Feb 2015 08:38

AW: Compiler Anweisung strict protected
 
Wenn man wirklich jede Klasse, und sei sie noch so klein, in eine eigene Unit packt, merkt man keinen Unterschied. Denkt man sich aber "die gehören zusammen, das kommt alles in eine Unit", dann führt strict private auch dazu, dass die Codevervollständigung den ganzen privaten Kram der jeweils anderen Klasse gar nicht erst anbietet, das erhöht die Übersicht.

[edit] Kleine Korrektur: da man strict private und private auch noch mischen kann, meinte ich ausdrücklich das strict private Gedöns, "nur" private wird weiterhin gelistet. [/edit]

ATS3788 12. Feb 2015 09:08

AW: Compiler Anweisung strict protected
 
Danke
für die Antworten. Werde diese durchlesen
und hoffentlich auch verstehen.

http://stackoverflow.com/questions/1...58763#16558763

Macht es ein wenig klarer.:thumb:

himitsu 12. Feb 2015 09:24

AW: Compiler Anweisung strict protected
 
Zitat:

Zitat von Daniel (Beitrag 1289602)
Wenngleich ich es in realen Projekten eher weniger einsetze - vermutlich aus Gewohnheit und weil "private" in einem Atemzug mit "protected" und "public" schneller geschrieben ist.

Ich "versuche" es geziehlt einzusetzen, wenn ich mehrere Komponenten in einer Unit entwickle, aber manchmal auch erst gegen Ende, um die Abhängigkeite zu prüfen, da ich es vorher vergssen hatte, um mich selber automatisch zu prüfen, ob ich nicht doch "ungewollte" Abhängigkeiten geschaffen hab.

Man könnte es so auch als Doumentation sehen, aber nur wenn man es schafft das konsequent durchzuziehen, denn so könnte man "wirklich" private Dinge strict machen und Teile, die zwischen Parent- und Child-Klasse "privat" geshared werden. :thumb:


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