Вы можете сделать это в 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. | |