![]() |
AW: was ist der Sinn von Templates/Generics ?
Zitat:
Delphi-Quellcode:
, oder wieder nach außen als neuen generischen Typ durchreichen, also
TSubClass = class(TMyValue<Integer>)
Delphi-Quellcode:
. Beides habe ich schon sehr oft verwendet.
TSubClass<T> = class(TMyValue<T>)
|
AW: was ist der Sinn von Templates/Generics ?
Delphi-Quellcode:
Sie Weiteres auch in der OH/DocWiki.
TMyValue = class
function GetValue<T>: T; procedure SetValue<T>(Value: T); end; TMyValue<T> = class function GetValue: T; procedure SetValue(Value: T); end; TMyValue<T> = class procedure Machwas<X>(Value: T; Other: X); end; * mehrere Typen können angegeben werden * es können Einschränkungen Mindestanforderungen für diese Typen vorgegeben werben * uvm. Es kann sogar eine teilweise Automatik (Inferenz) genutzt, wo der Compiler z.B. anhand der übergebenen Variable das T selbst bestimmt.
Delphi-Quellcode:
bei
MyValue.SetValue<Integer>(MyInt);
MyValue.SetValue(MyInt);
Delphi-Quellcode:
aber leider nicht bei
Value: T
Delphi-Quellcode:
Value: array of T
|
AW: was ist der Sinn von Templates/Generics ?
Zitat:
na gut, man kann nicht alles Haben (aber lieber auf der Bank ein Haben haben, als Soll zollen...) |
AW: was ist der Sinn von Templates/Generics ?
Delphi-Quellcode:
bei oben stehenden Code erhalte ich dann die Meldung:
type
QChar<T> = class public type QChar_Category = ( Mark_NonSpacing = 0, Mark_SpacingCombining = 1 ); private FCategory: QChar_Category; public constructor Create; published property Category: QChar_Category read FCategory default Other_NotAssigned; end;
Code:
und beim default Constructor erhalte ich dann:
[dcc64 Fehler] QCharClass.pas(392): E2146 Standardwerte müssen vom Typ Ordinal, Pointer oder vom Typ small Set sein
Code:
constructor QChar.Create;
[dcc64 Fehler] QCharClass.pas(419): E2003 Undeklarierter Bezeichner: 'QChar'
Delphi-Quellcode:
funktioniert dann wieder (als member function).
constructor QChar<T>.Create;
Ich habe das jetzt noch nicht weiter getestet; aber: dann ist ja auch:
Code:
nicht möglich, weil, dann fehlt ja Typ, den man eigentlich mit <T> im Epilog des Klassen-Codes angegeben hat ?
foo := QChar.Create;
|
AW: was ist der Sinn von Templates/Generics ?
Wie gesagt, man kann die Deklaration des Generics an den Typ/Klasse hängen, dann muß es immer angegeben werden, und betrifft die ganze Klasse.
Oder man hängt ihn an die Methode(n), wo es dann jeweils nur diese Methode betrifft und man den Typen selbst auch ohne nutzen kann. Oder man definiert sich eben einen aufgelösten Alias Typen damit.
Delphi-Quellcode:
type
QChar<T> = class ... end; QChar = QChar<string>; Zitat:
|
AW: was ist der Sinn von Templates/Generics ?
Zitat:
|
AW: was ist der Sinn von Templates/Generics ?
ich habe nun folgendes...
Delphi-Quellcode:
ergibt dann:
unit QCharClass;
interface type QChar<T> = class protected function getOrigin: uint64; public constructor Create; overload; ... end; implementation function check_ptr(name: PChar; ptr: uint64): Boolean; begin result := false; if ptr = 0 then begin ErrorMessage(PChar(Format('Error: %s not constructed.',[name]))); exit; end; result := true; end; constructor QChar<T>.Create; begin inherited Create; if not check_ptr(ClassName, getOrigin) then begin Free; exit; end; end; end.
Code:
heißt das nun, ich kann keine Funktionen/Prozeduren im implementation's-Bereich stehen, und nicht direkt mit der QChar<T> zu tun haben, mehr schreiben ?
[dcc64 Fehler] QCharClass.pas(429): E2506 Im interface-Abschnitt deklarierte Methode des parametrisierten Typs darf kein lokales Symbol 'check_ptr' verwenden
|
AW: was ist der Sinn von Templates/Generics ?
Bei einer generischen Klasse kann der Compiler den eigentlichen Code erst erzeugen, wenn der tatsächliche Typ von T bekannt ist. Daher gibt es diese Einschränkung.
Alternativ kannst du die
Delphi-Quellcode:
als Methode der Klasse deklarieren (dann wäre sie ja auch im Interface Part) oder als lokale function innerhalb von
function check_ptr
Delphi-Quellcode:
(wenn sie nicht noch anderswo verwendet wird).
QChar<T>.Create
Abgesehen davon sieht man in deinem Code gar nicht, warum er überhaupt generisch ist. Das T wird nirgendwo verwendet - zumindest nicht in dem Teil den du zeigst. Ich bringe das deswegen auf den Tisch, da es manchmal sinnvoller ist, eine nicht generische Basisklasse zu haben und von der dann ein generische Ableitung zu erstellen, die sich rein um den generischen Part kümmert.
Delphi-Quellcode:
Übrigens: das Free innerhalb des Create ist etwas irritierend.
type
QChar = class protected function getOrigin: uint64; public constructor Create; overload; ... // alles was nicht mit T zu tun hat end; QChar<T> = class(QChar) ... // alles was mit T zu tun hat end; implementation function check_ptr(name: PChar; ptr: uint64): Boolean; begin result := false; if ptr = 0 then begin ErrorMessage(PChar(Format('Error: %s not constructed.',[name]))); exit; end; result := true; end; constructor QChar.Create; begin inherited Create; if not check_ptr(ClassName, getOrigin) then begin Free; exit; end; end; |
AW: was ist der Sinn von Templates/Generics ?
Wozu Free?
Erst garnicht erzeugen, wenn nicht nötig oder möglich.
Delphi-Quellcode:
type
QChar = class private // or protected or public class function check_ptr(name: PChar; ptr: uint64): Boolean; static; protected function getOrigin: uint64; public //constructor Create; //class function Create: QChar; static; // intern nur dann erzeugen, wenn nötig class function CreateOrNot: QChar; static; // da dieses "Create" unerwartet auch NIL zurückgeben kann, sollte das auch ersichtlich sein. end; class function QChar.check_ptr(name: PChar; ptr: uint64): Boolean; begin Result := ptr <> 0; if not Result then ErrorMessage(PChar(Format('Error: %s not constructed.',[name]))); end; class function QChar.CreateOrNot: QChar; begin Result := nil; if check_ptr(ClassName, getOrigin) then Result := inherited Create; end; x := QChar.CreateOrNot; if Assigned(x) then ... |
AW: was ist der Sinn von Templates/Generics ?
Zitat:
Zitat:
Man könnte das auch auslagern. Aber ich dachte mir, da der Code in einer DLL liegt, das auslösen einer Exception nicht so dolle erscheinen mag. das ganze kann auch ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz