Delphi类参数

Ben*_*iss 3 delphi class

我正在尝试在 Delphi 中编写我自己的 ThreadManager 单元,到目前为止我已经有了:

unit uThreadManager;

interface

uses
  Classes,
  Windows;

type
  TCustomTThread = class (TThread)
  public
    TaskData : Pointer;
end;

type
  TWorkerThread = class(TObject)
  private
    TaskDataList : TList;
    TaskDataListCrit : TRTLCriticalSection;
    function ReadTotalTasks : Integer;
  public
    constructor Create;
    destructor Destroy; override;
    property TotalTasks : Integer read ReadTotalTasks;
    function AddTask(Thread: TCustomTThread; Data: Pointer) : Integer;
    procedure Delete (Index : Integer);
end;

implementation

type
  PTaskData = ^TTaskData;
  TTaskData = record
  Thread          : TCustomTThread;
  TaskPointer     : Pointer;
end;

procedure TWorkerThread.Delete(Index: Integer);
var
  TaskData : PTaskData;
begin
  EnterCriticalSection(TaskDataListCrit);
  TaskData := TaskDataList.Items[Index];
  TaskDataList.Delete(Index);
  LeaveCriticalSection(TaskDataListCrit);
  TaskData^.Thread.Free;
  Dispose(TaskData);
end;

function TWorkerThread.ReadTotalTasks;
begin
  EnterCriticalSection(TaskDataListCrit);
  result := TaskDataList.Count;
  LeaveCriticalSection(TaskDataListCrit);
end;

destructor TWorkerThread.Destroy;
begin
  DeleteCriticalSection(TaskDataListCrit);
  TaskDataList.Free;
  inherited;
end;

constructor TWorkerThread.Create;
begin
  inherited;
  InitializeCriticalSection(TaskDataListCrit);
  TaskDataList    := TList.Create;
end;

function TWorkerThread.AddTask(Thread: TCustomTThread; Data: Pointer) : Integer;
var
  NewTask : PTaskData;
begin
  EnterCriticalSection(TaskDataListCrit);
  New(NewTask);
  // I would like to create a new instance of TCustomTThread here!
  //NewTask^.Thread       := ...
  NewTask^.TaskPointer  := Data;
  result                := TaskDataList.Add (NewTask);
  LeaveCriticalSection(TaskDataListCrit);
end;

end.
Run Code Online (Sandbox Code Playgroud)

我在程序中遇到了参数问题AddTask......

这是我正在尝试做的事情的一个例子:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, uThreadManager;

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

type
  TTheCustomThread = class (TCustomTThread)
  public
    procedure Execute; override;
end;

implementation

{$R *.dfm}

procedure TTheCustomThread.Execute;
begin
 // My Code
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  NewWorkerThread : TWorkerThread;
begin
  NewWorkerThread := TWorkerThread.Create;
  NewWorkerThread.AddTask(TTheCustomThread, NIL);
end;

end.
Run Code Online (Sandbox Code Playgroud)

这段代码给了我错误:

[dcc32 错误] Unit2.pas(42): E2010 不兼容的类型:“TCustomTThread”和“TTheCustomThread 类”

我可以通过在堆栈中声明一个新的TTheCustomThreadvar 来解决这个问题,但我想避免这种情况,因为我以后根本不需要它,并且AddTask会创建一个新的TTheCustomThread. 我可以使用 TClass 然后进行类型转换TCustomThread,但我想知道是否还有其他方法可以完成这项工作。

感谢您的帮助。

Dav*_*nan 5

你的函数AddTask定义如下:

function AddTask(Thread: TCustomTThread; Data: Pointer) : Integer;  
Run Code Online (Sandbox Code Playgroud)

您传递的第一个参数的类型为TCustomTThread。这是的一个实例TCustomTThread

您可以这样调用该函数:

AddTask(TTheCustomThread, nil);
Run Code Online (Sandbox Code Playgroud)

在这里您传递的是类而不是实例。因此出现编译器错误。

现在看来,你想做的就是通过课程。在里面AddTask你希望接收一个类,然后创建一个新实例。像这样声明一个类类型:

type
  TTheCustomThreadClass = class of TTheCustomThread;
Run Code Online (Sandbox Code Playgroud)

更改AddTask为接收该类型:

function AddTask(ThreadClass: TCustomTThreadClass; Data: Pointer) : Integer;  
Run Code Online (Sandbox Code Playgroud)

在实现中,创建一个如下所示的实例:

NewTask^.Thread := ThreadClass.Create;
Run Code Online (Sandbox Code Playgroud)

您很可能希望将 的构造函数声明TTheCustomThread为虚拟的,以允许派生类自由定义可以从工厂创建机制执行的构造函数。