Forward Declarations

Imagine que você está escrevendo uma biblioteca de funções estáticas em um arquivo .pas e precisa declarar o cabeçalho de uma função para que ela possa ser usada abaixo globalmente, mas você não quer colocar o cabeçalho na seção interface para que a função não seja publicada para todas as units, você quer manter ela em "segredo" na seção de implementation.

Você pode dizer: "simples, basta declarar a função inteira acima e pronto." Mas e se essa função precisa usar outra que também será declarada dessa maneira e vice-versa?

A solução é foward declaration. Tudo bem, não se usa muito hoje em dia, ainda mais em POO, mas segue abaixo um exemplo de como você pode declarar uma função adiando a sua real implementação "mais para baixo" mesmo na seção implementation:

unit uSomaForward;

interface

function SomaPublica(x, y: Integer): Integer;

implementation


function SomaPrivada(x,y: Integer): Integer; forward;

function SomaPublica(x, y: Integer): Integer;
begin
  Result := SomaPrivada(x, y);
end;


function SomaPrivada(x,y: Integer): Integer;
begin
  Result := x+y;
end;


end.
 

Esse você testa com:

ShowMessage(IntToStr(SomaPublica(5,9))); 

Vamos fazer uma brincadeira mais complexa: todo mundo sabe fazer uma função fatorial recursiva certo? E se dividíssemos a função em duas recursivas circulares que hora chama uma e hora chama outra? Lógico que não teremos isso na vida real, mas você pode ter dois métodos um fazendo chamada ao outro de maneira circular por n motivos, desde tratamento de arvores de menus até mesmo descuido e desatenção. Isso não vem ao caso, queremos apenas demonstrar como as foward declarations podem ajudar a resolver quebra-cabeças de funções auto referenciaveis que ainda não foram declaradas. Sem elas não seria possível uma função chamar a outra sem os cabeçalhos, experimente.

A função fatorial dependente de duas recursivas ficaria assim:

unit uInterdependentes;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils;

function FatorialChamanoFuncoesRecursivasInterDependentes(numero: integer):integer;



implementation

   function InterDependente(contador: integer): integer forward;
   function DependenteInter(contador: integer): integer forward;

   function FatorialChamanoFuncoesRecursivasInterDependentes(numero: integer):integer;
   begin
        Result :=  InterDependente(numero);
   end;

   function InterDependente(contador: integer): integer;
   begin
        if contador <= 1 then
        begin
             Result := 1;
        end
        else
        begin
            Result := contador * DependenteInter(contador-1);
        end;
   end;

   function DependenteInter(contador: integer): integer;
   begin
        if contador <= 1 then
        begin
             Result := 1;
        end
        else
        begin
            Result := contador * InterDependente(contador-1);
        end;
   end;

end.  
E você pode testar assim:
     ShowMessage(IntToStr(FatorialChamanoFuncoesRecursivasInterDependentes(5)));  //retornará 120

Até a próxima ;)

Comentários

Postagens mais visitadas deste blog

Detectar o encoding de um arquivo para não corromper ao transformá-lo

erro "ora-12154: tns: não foi possível resolver o identificador de conexão especificado"

Quebras de linha no Delphi 2010