面向对象: 接口与对象生存周期,接口自动释放

相关资料:

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

 

posted on 2020-04-01 14:00  疯狂delphi  阅读(245)  评论(0编辑  收藏  举报

导航