因為看Delphi書的時候,就產生了疑惑。老講調用父類虛函數,但是萬一需要調用祖父虛函數怎么辦?
后來又經常在C++里看到,就更疑惑了
type TA = class procedure ShowMsg; virtual; end; TAClass = class of TA; TB = class(TA) procedure ShowMsg; override; end; TShowMsg = procedure of object; TC = class(TB) private FGrandFatherShowMsg: TShowMsg; procedure ShowMsg; override; public constructor Create; end; procedure TForm2.Button1Click(Sender: TObject); var C: TC; begin C := TC.Create; C.ShowMsg; C.Free; end; { TC } constructor TC.Create; var AMethod:TShowMsg; ACode: TMethod absolute AMethod; A: TA; begin inherited Create; A := TA.Create; FGrandFatherShowMsg := A.ShowMsg; AMethod:= FGrandFatherShowMsg; ACode.Data := Self; A.Free; end; procedure TC.ShowMsg; begin FGrandFatherShowMsg; ShowMessage('TC'); end; { TA } procedure TA.ShowMsg; begin ShowMessage('TA'); end; { TB } procedure TB.ShowMsg; begin inherited; ShowMessage('TB'); end;
利用了 Delphi 能夠創建純虛函數實例的特性
記錄下了TA的函數地址
然后替換其Data的值為Self,然后在需要的時候再調用
利用了兩點:TMethod和Delphi能夠創建純虛類實例
只是說萬一純虛的話,這個也好使
感謝 [長春]swish
----------------------------------------------------------
另一種辦法:
type TBase = class procedure Foo; virtual; end; TAnsestor = class(TBase) procedure Foo; override; end; TChild = class(TAnsestor) procedure Foo; override; procedure BaseFoo; end; procedure TBase.Foo; begin ShowMessage('TBase'); end; procedure TAnsestor.Foo; begin ShowMessage('TAnsestor'); end; procedure TChild.Foo; begin ShowMessage('TChild'); end; type TFoo = procedure of object; procedure TChild.BaseFoo; var Proc: TFoo; begin TMethod(Proc).Code := @TBase.Foo; // Static address TMethod(Proc).Data := Self; Proc(); end; procedure TForm4.Button1Click(Sender: TObject); var Obj: TChild; Proc: TFoo; begin Obj:= TChild.Create; Obj.BaseFoo; // or else TMethod(Proc).Code := @TBase.Foo; // Static address TMethod(Proc).Data := Obj; Proc(); Obj.Free; end;
http://stackoverflow.com/questions/4662744/delphi-how-to-call-inherited-inherited-ancestor-on-a-virtual-method
訣竅是搜索關鍵字“delphi inherited super parent”