Autor |
Beitrag |
tacl
Hält's aus hier
Beiträge: 13
WinXP, Linux, OS/2
Delphi2/2010 Prof., FoxPro, C++
|
Verfasst: Fr 16.07.10 09:33
Hi Leute,
ich glaub ich steh grad nur kräftig auf'm Schlauch und hoffe, dass mir jemand helfen kann.
Innerhalb einer Klasse definiere ich ein Feld, dass ich von klasseneigenen Methoden bearbeiten lassen möchte.
Eine Bearbeitung von ausserhalb der Instanz möchte ich verhindern. Jedoch soll das Feld möglichst ohne den Umweg über eine Methode ausgelesen werden können.
Die Symbole private und protected sind ja ungeeignet, da der Lesezugriff ja auch gesperrt wird.
Hat jemand die Lösung für mich?
Danke und Gruß
Patrick
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Fr 16.07.10 09:39
hi
Vielleicht kannst du den Zugriff über eine property gestalten:
Delphi-Quelltext 1: 2: 3: 4:
| private FMyField: TMyField; public property rOnly: TMyField read FMyField ; |
Propertys sind auch deshalb praktisch, weil man so später sehr einfach das Auslesen beispielsweise doch noch durch eine Funktion filtern lassen kann: Einfach read FMyField durch den Namen einer Funktion mit Rückgabewert TMyField ersetzen(sollte private/protected deklariert sein).
Hätte man die Funktion als public deklariert, müsste man für eine spätere Änderung des Aufrufs jeden einzelnen Aufruf getrennt umschreiben - von a := xyz auf P(xyz).
lg,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 16.07.10 09:49
Moin!
Ich denke, das ist nicht das, was er möchte. Vermutlich geht es um den Inhalt des Feldes, der soll read-only sein. AFAIK geht das nicht, wenn du das Feld rausreichst (und nicht nur ein Element per Index/Methode), dann geht immer beides, Lesen und Schreiben.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Fr 16.07.10 10:07
Wenn es sich bei dem Feld um ein Array oder einen ähnlichen, auf Pointern basierenden Typ geht, hast du recht, Narses. Da muss dann eine Funktion mit Argument her(Index übergeben). Die kann aber auch über eine Property gekapselt werden, und der Aufruf erfolgt wie bei Arrays.
Einfach gestrickte Prozeduren und Funktionen dürften vom Compiler aber inline umgesetzt werden, d.h. du bekommst unter Umständen sogar den selben Assembler-Code wie bei direktem Zugriff auf das Array oder hast zumindest kein push und call drin.
Ich habe tacl jetzt aber so verstanden, dass es sich bei dem Feld um eine Feldvariable handelt, also eine wie oben gezeigt in der Klasse deklarierten. Das ist dann genau der Anwendungsfall für Propertys.
lg,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
tacl 
Hält's aus hier
Beiträge: 13
WinXP, Linux, OS/2
Delphi2/2010 Prof., FoxPro, C++
|
Verfasst: Fr 16.07.10 10:41
Hallo zusammen,
vielen Dank für Eure Antworten!
Der Weg über eine Property ist wie für mich gemacht, da der Weg der Befüllung über einen gekoppelten Funktionsaufruf
Delphi-Quelltext 1:
| property StrVersion: String read GetVersion; |
für mich absolut elegant ist. Die erste Lösung über ein Feld sah so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| type TConfig = class(TObject) StrVersion: String; private function GetVersion:String; public constructor Create; end; |
Die Befüllung hätte dann für alle Felder im Constructor erfolgen müssen.
Da der Zugriff auf eine Property genauso erfolgt wie auf ein Feld, muss ich im vorgelagerten Quelltext nicht einmal etwas ändern.
Vielen Dank!!
Patrick
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 16.07.10 11:14
Moin!
OK, ich hab´s falsch verstanden, es ging also doch nicht um ein "Feld" (=array).
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
tacl 
Hält's aus hier
Beiträge: 13
WinXP, Linux, OS/2
Delphi2/2010 Prof., FoxPro, C++
|
Verfasst: Fr 16.07.10 11:20
Hi!
Nein, in diesem Fall ging es nicht um ein Array. Vor einem ähnlichen Problem werde ich wohl nächste Woche stehen,
wenn ich mich an den Errorhandler für mein Projekt begebe. 
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 24.07.10 09:50
Es gibt auch so etwas: Delphi-Quelltext 1: 2: 3: 4:
| private function GetData(Index: Integer): string; property Data[Index]: string read GetData; | Zudem kannst du, wenn du eine Klasse zurücklieferst, innerhalb dieser Klasse wiederum den Zugriff sperren. Dort gibt es die Möglichkeit über Interfaces private und protected Methoden nach außen sichtbar zu machen. Wenn man dann über die normale Klasse von außen zugreift, kommt man nicht heran, wenn man über das Interface zugreift schon. 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| type ITestClassFullAccess = interface procedure SetTest(const Value: string); end;
TTestClass = class(TInterfacedObject, ITestClassFullAccess) private FTest: string; protected procedure SetTest(const Value: string); function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; public property Test: string read FTest; end;
implementation
function TTestClass.QueryInterface(const IID: TGUID; out Obj): HResult; begin if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE; end;
function TTestClass._AddRef: Integer; begin Result := 1; end;
function TTestClass._Release: Integer; begin Result := 1; end;
procedure TTestClass.SetTest(const Value: string); begin FTest := Value; end; | Das Interface kannst du auch in eine andere Unit packen, damit man diese einbinden muss um Schreibzugriff zu bekommen. Jedenfalls kannst du dann das machen: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var a: TTestClass; begin a := TTestClass.Create(); try ITestClassFullAccess(a).SetTest('aaa'); ShowMessage(a.Test); finally a.Free(); end; | Ohne das Interface kommst du nur lesend an die Klasse heran.
|
|
|