'

‒ Arreglos abiertos Variant.

Cuando se usa el modo objfpc, free pascal soporta en las rutinas y métodos, parámetros arreglos abiertos variant, que en ingles sería: “variant open array parameters”.

Este es un caso especial de arreglos abiertos, donde este permite colocar cualquier elemento en un arreglo y pasarlo a un método o rutina. Los elementos deben ser tipos de datos enteros, booleanos, caracteres, Enumerados, subrangos, Reales, cadena de caracteres, punteros, clases y objetos.

Los elementos de un parámetro arreglo abierto variant, están asociados a un registro que nos permite obtener el valor colocado en el parámetro. Es decir un elemento de un parámetro arreglo abierto variant es un registro, en donde un campo nos permite identificar su tipo y el otro obtener el valor correspondiente. El campo vtType nos permitirá saber cual es el tipo de dato colocado en el arreglo, el cual debemos comparar con uno de las siguientes contantes:

Identificador Uso
vtInteger Para un tipo de dato integer.
vtBoolean Para un tipo de dato Boolean.
vtChar Para un tipo de dato Char.
vtWideChar Para un tipo de dato WideChar.
vtExtended Para un tipo de dato Eextended.
vtString Para un tipo de dato String.
vtPointer Para un puntero.
vtPChar Para un tipo de dato PChar.
vtObject Para un Objeto.
vtClass Para una Clase.
vtPWideChar Para un tipo de dato PWideChar.
vtAnsiString Para un tipo de dato AnsiString.
vtCurrency Para un tipo de dato Currency.
vtInt64 Para un tipo de dato Int64.
vtQWord Para un tipo de dato QWord.


Es decir si queremos saber si el elemento 3 de una lista X de elementos, tiene el tipo de dato entero, entonces usaremos lo siguiente:

if X[3].vtype=vtInteger then Writeln('Es un Entero')

Para obtener el valor colocado en un elemento se debe usar uno de los siguiente campos, según sea el caso:

Campos Uso
vInteger Para un tipo de dato integer.
vBoolean Para un tipo de dato Boolean.
vChar Para un tipo de dato Char.
vWideChar Para un tipo de dato WideChar.
vExtended Para un tipo de dato Eextended, se debe usar un circunflejo, ya que este es campo es un puntero de tipo Extended.
vString Para un tipo de dato String, igual se debe usar un circunflejo, ya que el campo es un puntero al tipo de dato String.
vPointer Para un puntero.
vPChar Para un tipo de dato PChar.
vObject Para un Objeto.
vClass Para una Clase.
vPWideChar Para un tipo de dato PWideChar.
vAnsiString Para un tipo de dato AnsiString.
vCurrency Para un tipo de dato Currency, también se debe usar circunflejo.
vInt64 Para un tipo de dato Int64, también se debe usar circunflejo.
vQWord Para un tipo de dato QWord, también se debe usar circunflejo.


Los parámetros arreglos abiertos variant, son útiles cuando no se sabe de antemano que es lo que se va a colocar en el arreglo. El siguiente programa es un ejemplo de como se podría, usar este tipo de parámetros:


Descargar
{$codepage utf8}
{$mode objfpc}

Uses sysutils;
Type

   TClassAvion=Class of TAvion;
   TAvion=class
      class var
        FAviones:integer;
      var
      Nombre:Unicodestring;
      constructor create;
      class function ObtAviones:integer; static;
      class property aviones:integer read ObtAviones;
      Procedure Despegar;virtual;abstract;
     End;

     TAvComercial=class(TAvion)
       Procedure Despegar;override;
     End;

     TAvGuerra=class(TAvComercial)
      Procedure Despegar;override;
     End;

     TEscenario=Class
       Ref:TClassAvion;
       A:array of TAvion;
       Procedure GenerarAviones(Aviones: Array of const;
                                Tipos:array of TClassAvion);
     End;

     Constructor TAvion.create;
      Begin
        inherited create;
        Faviones +=1
      End;

     Class function TAvion.ObtAviones:integer;
      Begin
       ObtAviones:=FAviones
      End;

     Procedure TAvComercial.Despegar;
      Begin
        Writeln('Despegando Avion Comercial '+Nombre);
      End;
     Procedure TAvGuerra.Despegar;
      Begin
        Writeln('Despegando Avion de Guerra '+Nombre);
      End;

    Procedure TEscenario.GenerarAviones(Aviones: Array of const;
                                        Tipos:array of TClassAvion);
     var i:integer;
         nombre:unicodestring;
     Begin
      setlength(A,length(Aviones));

      If (High(Aviones)>0) and (High(Aviones)=High(Tipos)) then
        Begin
         For i:=0 to High(Aviones) do
           begin
             case Aviones[i].vtype of
               vtinteger       : nombre:=IntToStr(Aviones[i].vinteger);
               vtextended      : nombre:=FloatToStr(Aviones[i].VExtended^);
               vtchar          : nombre:=Aviones[i].vchar;
               vtPChar         : nombre:=Aviones[i].VPChar;
               vtansiString    : nombre:=ansiString(Aviones[i].VansiString);
               vtUnicodeString : nombre:= 
                                 UnicodeString(Aviones[I].VUnicodeString);
               vtString        : nombre:=Aviones[i].VString^;
               vtInt64         : nombre:=IntToStr(Aviones[i].vint64^);
               vtQWord         : nombre:=IntToStr(Aviones[i].vQword^);
             else
               nombre:='Desconocido-'+IntToStr(Aviones[i].vtype);
             end;
             A[i]:=Tipos[i].create;
             A[i].Nombre:=nombre;
             A[i].despegar;
           end;
        end
       else Writeln('Faltan aviones o sus tipos correspondientes')
     End;

Var Escenario:TEscenario;
Begin
  Escenario:=TEscenario.create;
  Escenario.GenerarAviones([78,'Falcon',89.45,'F11-A'],
                    [TAvComercial,TAvGuerra,TAvComercial,TAvComercial])
End.
Código fuente 23: Ejemplo del uso de parámetros arreglos abiertos variant.
Descargar