zoukankan      html  css  js  c++  java
  • 面向对象: 接口与对象生存周期,接口自动释放

    相关资料:

    https://www.baidu.com/link?url=yYEHJesIUg6HguekaIW-U0HtjtLn430Dh0NXSc7ej5ixppqcq21rsYMvlCo_qNOP&wd=&eqid=87bf080a00000c50000000035e83f9e4

    实例:

    接口单元(UnInterface.pas):

     1 unit UnInterface;
     2 
     3 interface
     4 uses
     5   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
     6   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ToolWin, Vcl.ActnMan;
     7 
     8 type
     9   IFormInterface = interface(IInterface)
    10   ['{51869234-9F24-4409-A61D-C6A1A47E7E53}']
    11   procedure ShowForm stdcall;
    12   procedure HideForm stdcall;
    13   end;
    14 
    15   TFormInterface = class(TForm, IInterface, IFormInterface)
    16 //  TFormInterface = class(TForm, IFormInterface)
    17   private
    18     { Private declarations }
    19     protected FRefCount: Integer;
    20     function QueryInterface(const IID: TGUID; out Obj): HResult; override; stdcall;
    21     function _AddRef: Integer stdcall;
    22     function _Release: Integer stdcall;
    23     procedure ShowForm stdcall;
    24     procedure HideForm stdcall;
    25   public
    26     constructor Create(AOwner: TComponent); override;
    27 
    28     procedure AfterConstruction; override;
    29     procedure BeforeDestruction; override;
    30     class function NewInstance: TObject; override;
    31   property RefCount: Integer read FRefCount;
    32   end;
    33 
    34 implementation
    35 
    36 
    37 procedure TFormInterface.AfterConstruction;
    38 begin
    39   InterlockedDecrement(FRefCount);
    40 end;
    41 
    42 procedure TFormInterface.BeforeDestruction;
    43 begin
    44   if RefCount <> 0 then
    45   raise EInvalidPointer.Create('Invalid ptr');
    46 end;
    47 
    48 constructor TFormInterface.Create(AOwner: TComponent);
    49 begin
    50   inherited CreateNew(AOwner);
    51 end;
    52 
    53 function TFormInterface._AddRef: Integer;
    54 begin
    55   Result := InterlockedIncrement(FRefCount);
    56 end;
    57 
    58 function TFormInterface._Release: Integer;
    59 begin
    60   Result := InterlockedDecrement(FRefCount);
    61   if Result = 0 then
    62   Destroy;
    63 end;
    64 
    65 class function TFormInterface.NewInstance: TObject;
    66 begin
    67   Result := inherited NewInstance;
    68   TFormInterface(Result).FRefCount := 1;
    69 end;
    70 
    71 function TFormInterface.QueryInterface(const IID: TGUID; out Obj): HResult;
    72 begin
    73   if GetInterface(IID, Obj) then
    74   Result := 0
    75   else
    76   Result := E_NOINTERFACE;
    77 end;
    78 
    79 procedure TFormInterface.HideForm;
    80 begin
    81   Hide;
    82 end;
    83 
    84 procedure TFormInterface.ShowForm;
    85 begin
    86   Show;
    87 end;
    88 
    89 end.
    View Code

    调用单元(Unit1.pas):

     1 unit Unit1;
     2 
     3 interface
     4 
     5 uses
     6   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
     7   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ToolWin, Vcl.ActnMan,
     8   IdGlobal,
     9   UnShare,
    10   UnInterface;
    11 
    12 type
    13   TForm1 = class(TForm)
    14     Button1: TButton;
    15   procedure Button1Click(Sender: TObject);
    16   private
    17     { Private declarations }
    18     FIForm: IFormInterface;
    19   public
    20     { Public declarations }
    21   end;
    22 
    23 var
    24   Form1: TForm1;
    25 
    26 implementation
    27 {$R *.dfm}
    28 
    29 procedure TForm1.Button1Click(Sender: TObject);
    30 var
    31   iForm: IFormInterface;
    32 begin
    33 //  运行程序,按下Button1,会看到一个窗体出现,2秒钟后它消失了,这就实现了自动释放的功能
    34 //  iForm := TFormInterface.Create(nil) as IFormInterface;
    35 //  iForm.ShowForm;
    36 //  Sleep(2000);
    37 //  在Form1中定义一个成员变量,是一个IFormInterface型的接口,则对象能保持到程序退出时,Form1被释放时自动释放
    38 //  写成TFormInterface.Create(Self)的话会出现释放的问题
    39   iForm := TFormInterface.Create(nil) as IFormInterface;
    40   iForm.ShowForm;
    41   FIForm := iForm;
    42 end;
    43 end.
    View Code

     之前遇到过的一段代码没有理解意思,留下来方便以后学习:

     1 //功能: 直接解读对象内存结构,返回自身实现的对象
     2 //参数:
     3 //注意:对 x64 的修改,参考 https://forums.embarcadero.com/thread.jspa?threadID=62328
     4 ////////////////////////////////////////////////////////////////////////////////
     5 function GetImplObject(const AIntf: IInterface): TObject;
     6 {$IFDEF CPUX64}
     7 begin
     8   try
     9     Result := AIntf as TObject;
    10   except
    11     Result := nil;
    12   end;
    13 end;
    14 {$ELSE}
    15 const
    16   AddByte = $04244483; // opcode for ADD DWORD PTR [ESP+4], Shortint
    17   AddLong = $04244481; // opcode for ADD DWORD PTR [ESP+4], Longint
    18 type
    19   PAdjustSelfThunk = ^TAdjustSelfThunk;
    20   TAdjustSelfThunk = packed record
    21     case AddInstruction: Longint of
    22       AddByte: (AdjustmentByte: ShortInt);
    23       AddLong: (AdjustmentLong: Longint);
    24   end;
    25   PInterfaceMT = ^TInterfaceMT;
    26   TInterfaceMT = packed record
    27     QueryInterfaceThunk: PAdjustSelfThunk;
    28   end;
    29   TInterfaceRef = ^PInterfaceMT;
    30 var
    31   QueryInterfaceThunk: PAdjustSelfThunk;
    32 begin
    33   try
    34     Result := Pointer(AIntf);
    35     if Assigned(Result) then
    36     begin
    37       QueryInterfaceThunk := TInterfaceRef(AIntf)^.QueryInterfaceThunk;
    38       case QueryInterfaceThunk.AddInstruction of
    39         AddByte:
    40           Inc(PAnsiChar(Result), QueryInterfaceThunk.AdjustmentByte);
    41         AddLong:
    42           Inc(PAnsiChar(Result), QueryInterfaceThunk.AdjustmentLong);
    43       else
    44         Result := nil;
    45       end;
    46     end;
    47   except
    48     Result := nil;
    49   end;
    50 end;
    51 {$ENDIF}
    View Code
  • 相关阅读:
    原生js实现outerWidth()方法,用到getComputedStyle
    正则取数字
    关于JavaScript的各种width
    原生JavaScript根据类名获取元素
    通过DriveManager类实现数据库MySQL的连接
    org.apache.http.conn.HttpHostConnectException: Connection to xxx refused.
    C# 序列化原因 (转)
    C# 序列化理解 2(转)
    C# 序列化理解 1(转)
    C# using一般用法 (转)
  • 原文地址:https://www.cnblogs.com/FKdelphi/p/12612159.html
Copyright © 2011-2022 走看看