将指针传递给构造函数作为参数的问题

boi*_*eau 2 delphi delphi-2009

我有以下超类:

unit DlgDefaultForm;

type
  TDefaultFormDlg = class(TForm)
  published
    constructor Create(AOwner: TComponent); reintroduce; virtual; 
  end;

  FormCreateFunc=function(AOwner: TComponent):TDefaultFormDlg;
Run Code Online (Sandbox Code Playgroud)

这是由一堆形式下降,如下所示:

unit Form1

type
  TForm1 = class(TDefaultFormDlg)
  published
    constructor Create(AOwner: TComponent); override;
  end;
Run Code Online (Sandbox Code Playgroud)

并创建如下:

unit MainForm;

procedure ShowForm(FormCreate:FormCreateFunc);
begin
  (do some stuff)
  FormCreate(ScrollBox1);
end;
Run Code Online (Sandbox Code Playgroud)

我跑的时候

ShowForm(@TForm1.Create);
Run Code Online (Sandbox Code Playgroud)

发生了两件事:

  1. 当我进入TForm1.Create时,AOwner = nil,即使它没有在ShowForm中.

  2. 我在以下行获得了EAbstractError:

    unit Forms;
    (...)
    constructor TCustomForm.Create(AOwner: TComponent);
    begin
      (...)
      InitializeNewForm; //EAbstractError
      (...)
    end;
    
    Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

编辑:这当然不是我的确切代码.

Bar*_*lly 8

Delphi构造函数采用隐藏的额外参数来指示两件事:是否NewInstance需要调用,以及隐式第一个参数(Self)的类型是什么.从类或类引用中调用构造函数时,实际上需要构造一个新对象,Self参数的类型将是实际的类类型.从另一个构造函数调用构造函数时,或者在调用继承的构造函数时,已经创建了对象实例并将其作为Self参数传递.隐藏的额外参数充当Boolean标志,True用于分配新实例但False用于构造函数的方法样式调用.

因此,您不能简单地将构造函数存储在方法指针[1]位置并期望它工作; 调用方法指针不会传递隐藏的额外参数的正确值,它会中断.你可以通过明确声明参数并进行类型转换来解决它.但通常直接使用元类(类引用)更为可取且不易出错.

[1]这是你的代码的另一个问题.您正在尝试将方法指针存储在函数指针位置.你可以这样做并仍然使它工作,但是你需要Self明确地声明in,并且你还需要在分配时传递元类作为第一个参数(以及为隐式标志传递True) ).方法指针在第一个参数中烘焙并自动传递.为了使它全部显式,相当于的函数指针TComponent.Create是这样的:

TComponentCreate = function(Self: Pointer; AOwner: TComponent; DoAlloc: Boolean): Pointer;
Run Code Online (Sandbox Code Playgroud)

Self这是一个指针,因为它可以是TComponentClass类型或TComponent类型,具体取决于DoAlloc是真还是假.