如何从Delphi中的子类获取基类中方法的指针?
下面是我的代码示例:如何从Delphi中的子类获取基类中方法的指针?,delphi,Delphi,下面是我的代码示例: type TMyBaseClass = class public procedure SomeProc; virtual; end; TMyChildClass = class(TMyBaseClass) public procedure SomeProc; override; end; var SomeDelegate: procedure of object; procedure TMyBaseClass.SomePro
type
TMyBaseClass = class
public
procedure SomeProc; virtual;
end;
TMyChildClass = class(TMyBaseClass)
public
procedure SomeProc; override;
end;
var
SomeDelegate: procedure of object;
procedure TMyBaseClass.SomeProc;
begin
ShowMessage('Base proc');
end;
procedure TMyChildClass.SomeProc;
begin
ShowMessage('Child proc');
// here i want to get a pointer to TMyBaseClass.SomeProc (NOT IN THIS CLASS!):
SomeDelegate := SomeProc;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMyChildClass.Create do
try
// there will be "Child proc" message:
SomeProc;
finally
Free;
end;
// there i want to get "Base proc" message, but i get "Child proc" again
// (but it is destroyed anyway, how coud it be?):
SomeDelegate;
end;
我知道的一个方法是:
procedure TMyChildClass.BaseSomeProc;
begin
inherited SomeProc;
end;
procedure TMyChildClass.SomeProc;
begin
ShowMessage('Child proc');
SomeDelegate := BaseSomeProc;
end;
第二个是将SomeProc
声明从override
更改为重新引入
:
TMyChildClass = class(TMyBaseClass)
public
procedure SomeProc; reintroduce;
end;
然后将self
转换为TMyBaseClass
(不要使用as
cast):
还要注意的是,您的代码将导致访问冲突,因为您对已释放的对象调用了
SomeDelegate
。添加类型声明和一些类型转换是有效的,但会附带一些警告说明
正如您自己所提到的,在实例被释放后调用somedelegate并不正确。这是因为您的SomeProc方法不使用任何实例变量,它所做的只是调用ShowMessage
如果您向调用中添加了任何实例变量,如果内存没有被重新分配,您甚至可能会侥幸逃脱。这将是一个等待发生的AV
底线:
- 不要取消已销毁对象的方法李>
- 从类的实例中设置一个在类的生存期内仍然存在的全局变量被认为是不好的设计
- 在理想的设计中,除了通过调用继承的方法外,不需要子类以任何方式将调用还原到祖先的方法
...
type
TSomeDelegate = procedure of object;
var
SomeDelegate: TSomeDelegate;
...
procedure TMyChildClass.SomeProc;
var
method: TMethod;
begin
ShowMessage('Child proc');
// here i want to get a pointer to TMyBaseClass.SomeProc (NOT IN THIS CLASS!):
method.Code := @TMyBaseClass.SomeProc;
method.Data := Self;
SomeDelegate := TSomeDelegate(method);
end;
谢谢您的第一种方法正是我想要的=)请注意Michal Niklas关于访问违规的说法。你仍然会得到一个,即使是“继承的”。这是因为您不能有一个指向类的方法的指针(除非它声明为“类过程”),而只能指向对象的方法。调用Free()时,对象将被销毁,对它的任何引用(包括包含对其函数引用的SomeDelegate)都不再有效。使用我的Turbo Delphi编写代码时,我遇到访问冲突异常。
...
type
TSomeDelegate = procedure of object;
var
SomeDelegate: TSomeDelegate;
...
procedure TMyChildClass.SomeProc;
var
method: TMethod;
begin
ShowMessage('Child proc');
// here i want to get a pointer to TMyBaseClass.SomeProc (NOT IN THIS CLASS!):
method.Code := @TMyBaseClass.SomeProc;
method.Data := Self;
SomeDelegate := TSomeDelegate(method);
end;