Советы по Delphi

         

Функция, возвращающая тип


Вы можете сделать это в C++. В ObjectPascal это также можно сделать, смотрите пример:

    // функция Chameleon, возвращающая тип сгенерированного исключения

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;


type

MyBoolean = class public Value : boolean; end;
MyInteger = class public Value : integer; end;
MyClass = class public Value : TStrings; end;
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure MyProc; function Chameleon : boolean; end;
var
Form1: TForm1;
implementation

{$R *.DFM}

function TForm1.Chameleon : boolean;
var
b : MyBoolean; i : MyInteger; c : MyClass; r : integer; begin
r := Random(3); case r of 0 : begin b := MyBoolean.Create; raise b; end; 1 : begin i := MyInteger.Create; raise i; end; 2 : begin c := MyClass.Create; raise c; end; end; end;

procedure TForm1.MyProc;
begin
try
Chameleon; except on MyBoolean do ShowMessage('Функция возвратила класс MyBoolean'); on MyInteger do ShowMessage('Функция возвратила класс MyInteger'); on MyClass do ShowMessage('Функция возвратила класс MyClass'); end; end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Chameleon; end;

end.

Взгляните на тип данных Variant в D2: следующий код

    function AnyType(const TypeParm: integer): Variant;
begin
case
TypeParm of 1:  Result := 1; 2:  Result := 2.0; 3:  Result := 'Три'; 4:  Result := StrToDate('4/4/1944'); end; end;

абсолютно бестолковый, но полностью корректный!

Следующий код содержит объявление трех функций, принимающих на входе один и тот же параметр, но выдающих результаты различных типов (результат физичиски один и тот же, и занимает он 4 байта). Я не думаю, что можно одурачить delphi, чтобы с помощью этого метода возвратить строку. Это может привести к разрушению менеджера кучи. Вместо этого вызывайте необходимую вам функцию. Каждый вызов передается MyFuncRetAnything, а P1 определяет возвращаемый тип. Если хотите, можете написать другую обертку, делающую для вас еще и приведение типов.

3 вызова, 1 код.

Я понимаю, что это в действительности не то, что нужно, по я просто хотел продемонстрировать другой способ. (вы можете возвращать строки как тип PChar, который также занимает 4 байта). Вы должны использовать некоторую память, распределяемую вызовом процедуры (может быть передавать результаты как P2?).

    {моя форма имеет 3 метки, одну кнопку и этот код}

var
MyFuncRetInt : Function (P1, P2 : Integer) : Integer; MyFuncRetBool : Function (P1, P2 : Integer) : LongBool; MyFuncRetPointer : Function (P1, P2 : Integer) : Pointer;
function MyFuncRetAnything (P1, P2 : Integer) : Integer;
var
RetPointer : Pointer; RetBool : LongBool; RetInteger : Integer; begin
RetPointer := nil; RetBool := False; RetInteger := 4711; case P1 of 1 : Result := Integer (RetPointer); 2 : Result := Integer (RetBool); 3 : Result := RetInteger; end; end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if
MyFuncRetBool (2, 1900) then Label1.Caption := 'True' else Label1.Caption := 'False'; Label2.Caption := IntToStr (MyFuncRetInt (3, 1900)); Label3.Caption := IntToHex (Integer (MyFuncRetPointer (1, 1900)), 16); end;

initialization
MyFuncRetInt := @MyFuncRetAnything; MyFuncRetBool := @MyFuncRetAnything; MyFuncRetPointer := @MyFuncRetAnything; end.

[001192]



Содержание раздела