Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#1

Interfaces UND Objektreferenzen mischen

  Alt 6. Nov 2011, 09:25
Im Prinzip benötige ich sowas für eine Art Framework, wo man eigene Objekte, eigene Interfaces und fremde Interfaces (gekpselt in eigenen Objekten) paralell nutzen kann.
Also wo ein objekt gleichzeitig als Objektreferenz existiert und als Interface.

Leider ging es nicht "einfach", da http://www.delphipraxis.net/164271-d...ml#post1134663 nicht möglich ist.
Und leider bekommt man im constructor nicht mit, ob das erzeugte Objekt, danach als Objekt oder als Interface genutzt wird. (das zusätzliche CreateIntf erspart)


Delphi-Quellcode:
type
  _RefObject = class abstract(TObject)
  private
    FRefCount: Integer;
    FVCLFreed: Boolean;
    FNoDestroy: Integer;
    class function _NewInstance: TObject; virtual; abstract;
    procedure _FreeInstance; virtual; abstract;
    procedure _AfterConstruction; virtual; abstract;
    procedure _BeforeDestruction; virtual; abstract;
    destructor _Destroy; virtual; abstract;
  public
    class function NewInstance: TObject; override;
    procedure FreeInstance; override;
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    destructor Destroy; override;
  end;
  TRefObject = class(_RefObject, IInterface)
    class function _NewInstance: TObject; override;
    procedure _FreeInstance; override;
    procedure _AfterConstruction; override;
    procedure _BeforeDestruction; override;
    destructor _Destroy; override;
  public
    class function NewInstance: TObject; reintroduce; virtual;
    procedure FreeInstance; reintroduce; virtual;
    procedure AfterConstruction; reintroduce; virtual;
    procedure BeforeDestruction; reintroduce; virtual;
    constructor Create; overload; virtual;
    constructor CreateIntf; overload;
    class function CreateIntf<I: IInterface>: I; overload;
    destructor Destroy; reintroduce; virtual;
    { IInterface }
    function QueryInterface(const IID: TGUID; out Obj): HRESULT; virtual; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  end;
Es wird also nun jeweils erst bei dem wirklich freigegeben, welches zurletz noch vorhanden ist.
Womit dann z.B. Sowas gemacht werden könnte:
Delphi-Quellcode:
var
  i: IInterface;
  o: TRefObject;
begin

o := TRefObject.Create;
o.Free;

i := TRefObject.CreateInf;
i := nil;

o := TRefObject.Create;
i := o as IInterface;
i := nil;
o.Free;

o := TRefObject.Create;
i := o as IInterface;
o.Free;
i := nil;

TRefObject.Create.Free;
Das Ganze ist also quasi eine Mischung aus einem Interface-Pattern und einem Singleinstanz-Pattern.

Wäre schön, wenn da nochmal wer reinsehn könnte ... nicht daß ich da noch irgendwas übersehn hab.

Wenn jemand an der Referenzzählung (_AddRef und _Release) rumspielt oder wenn wer Free/Destroy doppelt aufruft, dann knallt es natürlich irgendwo, aber sowas passiert ja auch bei den normalten Objekten und Interfacen, weswegen ich da keinen Anlaß sah, Dieses (zumindestens das Free/Destroy) entsprechend zu behandeln ... zu oft _Release wird aber erkannt.
Angehängte Dateien
Dateityp: pas VTAControls.pas (7,1 KB, 6x aufgerufen)
$2B or not $2B
  Mit Zitat antworten Zitat