Você está na página 1de 7

Pequenos Segredos do Delphi

Por Anderson Haertel Rodrigues


Artigo publicado na revista The Club - Edio Nr. 102 - Maro/2003

Introduo O artigo deste ms no tem a inteno de manter uma lgica e nem falar em apenas um ass especfico. Ento se mudarmos de assunto radicalmente no prximo tpico, no estranhe! Irei falar sobre algumas palavras que vemos no Delphi e s vezes no sabemos de onde a mesma vem e nem o que existe por trs da mesma. Mas tambm, falarei de algumas palavras chaves d Delphi. Result A primeira delas que veremos a palavra Result. Quando implementamos uma funo (mtodo): {...} type TForm1 = class(TForm) private { Private declarations } function Soma(pnSoma1, pnSoma2: Double): Double; public { Public declarations } end; {...} function TForm1.Soma(pnSoma1, pnSoma2: Double): Double; begin Result := pnSoma1 + pnSoma2; end; J parou para pensar de onde vem Result? R. Eu j :-). Result uma varivel. Cada funo (ou mtodo) declara implicitamente a varivel Result, cujo, o tip da varivel o mesmo tipo de retorno da funo declarada. No exemplo acima, do tipo Double Result no uma varivel Local ela semelhante a um parmetro var oculto, j declarado no cabealho da function (isso ocorre nos bastidores). Uma dica: O Delphi pode falhar ao inicializar a varivel Result, principalmente em alguns ca envolvendo o retorno de String, Arrays Dinmicos e Variant. Nesses casos, por segurana, de inicializar a mesma com: String Vazia, Array Vazio e ou Unassigned (declarada na Uses Variants do Delphi 7). Self E Self?

R. Eu j (de novo) :-). Self assim como Result uma varivel. Self s visvel em Mtodos que pertencem a uma Classe e no visvel em Functions e Procedures normais. Self um parmetro oculto e tem como va Referncia ao Objeto ou, se for o caso de um Mtodo de Classe (Class methods) Self a Referncia da Classe. No exemplo acima do mtodo Soma, Self receberia o valor de: TForm1. Uma coisa interessante mtodos possuem um with Self do implcito no corpo do mtodo, isto , por isso que quando fizemos o seguinte no corpo de um mtodo no precisamos colocar Self: function TForm1.Soma(pnSoma1, pnSoma2: Double): Double; begin Caption := 'Artigo escrito por AHR'; Close; {...} end; Como o mtodo est envolvido num with Self do implcito (como j explicado) no precisamos fazer: Self.Caption, Self.Close, etc, etc. Const E const? R. Voc deve estar cansado de ler (Eu j)...... Const uma palavra chave, no uma varivel inicializada implicitamente (pelo compilador) como Self e Result (explicados mais acima). A palavra Const no possui mistrio algum para explicar. O que tem de mistrio para explicar na palavra chave const como a mesma se comporta conforme a sua declarao e se ligarmos (no Delphi 7) a diretiva de compilao {$J+} ou {$WRITEABLECONS ON}. Const pode ser de dois tipos: Constantes (propriamente dita) ou Constantes Tipificadas. Constantes (constantes mesmo!) como estamos acostumados a trabalhar, isto , no podemos modificar o seu valor dentro de rotinas, por que, o prprio compilador impe essa restrio, onde, voc tentar mudar o valor da mesma, o compilador ir emitir uma mensagem de erro. Constantes Tipificadas no realmente uma constante, e sim, uma varivel inicializada, isto , o Delphi trata a mesma como sendo uma varivel. Mas, existe uma diferena entre constantes tipificadas e variveis normais locais, Constantes tipificadas mantm o seu valor entre as chamadas de rotinas, coisa que no acontece com uma varivel local normal, onde, a mesma sempre inicializada conforme o seu tipo. Vamos aos exemplos para ficar mais claro: implementation {$J+} // Ou {$WRITEABLECONST ON} const constMesmo = 42; constTipificada: Integer = 7;

consObjeto: TForm = nil; {$J-} // Ou {$WRITEABLECONST OFF} {$R *.dfm} No exemplo acima eu liguei a diretiva de compilao {$J+} (tambm poderia ser {$WRITEABLECONST ON}), do qual indica que poderemos mudar o valor da constante (m lembre-se, mesmo ligando a diretiva, ainda necessito especificar o Tipo para a mesma ser re Constante Tipificada): procedure TForm1.Button1Click(Sender: TObject); begin //constMesmo := 10; constTipificada := 10; consObjeto := TForm1.Create(Self); consObjeto.Name := 'TESTE'; ShowMessage(IntToStr(constTipificada)); ShowMessage(consObjeto.Name); end; Ao colocarmos o cdigo no Evento OnClik do Boto (que foi adicionado no Form), podemos percebe que nem o compilador e muito menos em tempo de execuo tivemos alguma mensagem de erro Mas, como citado, s podemos modificar o valor de constTipificada e consObjeto, pois, amba declaradas com o seu tipo, tornando assim, ambas como constantes tipificadas. Quis tambm usar um Objeto para vermos que tambm podemos fazer o uso de variveis incializadas com Objetos. Mesmo ligando as diretivas acima, constMesmo constante mesmo, isto , no podemos modificar seu valor, se tentarmos, receberemos uma mensagem de erro do compilador do Delphi. Para fazermos o teste, basta retirarmos o comentrio de constMesmo. Vamos colocar um novo boto no Form para testarmos outro aspecto das constantes tipificadas, que (como j citado) o fato de Constantes tipificadas manterem o seu valor entre as chamadas de rotinas. Exemplo: procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage(IntToStr(constTipificada)); constTipificada := constTipificada + 10; end;

Ao clicarmos novamente no Boto:

E se clicarmos novamente, ir sempre adicionar mais 10 (Dez) ao valor da constante tipificad conforme o cdigo do exemplo do Button2. No Delphi 7 tanto {$J} como {$WRITEABLECONST OFF} por Default esto desligados, ento (isso no acontecia em verses anteriores), sendo assim, constantes tipificadas so verdadeiramente constantes. Class A palavra chave Class tambm no tem mistrios. O que existe de diferente a forma como a mesma pode ser declarada. Isto , conforme a declarao podemos ter muitas nuances com a mesma palavra, exemplo: type TForm1 = class(TForm) private public end; {...} a forma normal que usamos no dia a dia, e estamos apenas indicando (a IDE fez este trabalho acima por ns) que TForm1 herda da Classe TForm. J: TCustomForm = class; uma declarao antecipada (chamada de: Forward declarations), onde estamos apenas diz compilador que a classe ser declarada mais adiante na rotina. Se olharmos o fonte da unit: Forms.pas veremos muitas declaraes deste tipo. J: TFormClass = class of TForm; uma declarao do tipo MetaClasse. Onde, uma MetaClasse uma varivel que pode armazenar uma referncia da classe que poder ser usada em qualquer expresso que exija a referncia de classe, como ao chamar um construtor ou mtodo de classe. Observao: Citei em vrias partes do Artigo Referncia de Classe, no se preocupe, mais a fren explico com detalhes o que uma Referncia de Classe. J: type TAlgumaClasse = class

public class function AlgumaFunction(Operation: string): Boolean; virtual; class procedure AlgumaProcedure(var Info: TFigureInfo); virtual; {...} end; O principal da declarao : class function AlgumaFunction(Operation: string): Boolean; virtual; class procedure AlgumaProcedure(var Info: TFigureInfo); virtual; O cabealho e o corpo da implementao devem comear com: class function. Class method um mtodo que opera sobre a classe e no sobre a instncia dessa classe. Eles podem ser executados sem a necessidade se criar o objeto da classe. IS O operador is no tem mistrios, is uma palavra chave e ele apenas testa se o tipo de referncia do objeto igual a uma referncia de classe e ou de uma das suas classes derivadas. Mas, nas internas o operador is chama o mtodo InheritsFrom do Objeto para saber o seu tipo correto. A dica do operador is , ao testar o objeto com is no necessrio usar o operador as, neste caso, faa um type casting simples para conseguir um melhor desempenho. NIL um valor do tipo Pointer especial (Pointer(0)). Seu valor numrico 0 (Zero). O uso mais comum para NIL marcar variveis do tipo Pointer e mtodos para um valor desconhecido. Um exemplo seria o manipulador de eventos, onde, podemos atribuir o mesmo para nil: Button1.OnClick := nil; No fizemos nada de mais no exemplo acima, apenas matamos o endereo do mtodo. Uma caracterstica e curiosidade, o Delphi armazena um Array Dinmico e String longa como u ponteiro nil. with O que with faz apenas acrescentar uma referncia de registro, Objeto, Classe e ou Interface a escopo para resolver nomes de smbolo. Diferena entre TStrings e TStringList J parou para pensar qual a real diferena entre TStrings e TStringList? R. Eu j ;-). Listas de Strings esto por toda a parte, na VCL, no Mar, no Ar e at mesmo em Marte! ;-) Brincadeiras a parte, elas esto por todo o lugar mesmo: Caixa de Listas, Controles de Edies Controle de Menu, Listas de Strings, etc, etc. Apesar de serem fceis de usar e bastante funcional, ela vitima muitos desenvolvedores com a seguinte pergunta: E agora? Uso TStrings ou TStringList? No fundo, qual a diferena entre elas? R.: A combinao de ambas! TStrings uma classe que define todo o comportamento associado a lista de Strings. Entretan

TStrings no tem qualquer mtodo e/ou recursos para realmente manter a lista de Strings descendentes de TStrings que so responsveis por isso, neste caso, TStringList. Ok, Ok.... ento agora no necessito mais usar TStrings e apartir de agora s usarei TStringList! Certo? R.: Errado! Fazendo isso voc perde um poderoso recurso da Classe TStrings, que o recurso de cpia de um Lista de String para outra Lista de String, usando o mtodo Assign. Diante disso, voc deve declarar a varivel como TStrings e na criao da mesma, criar usando a referncia de classe TStringLis TStringList herdada de TStrings. Algo como: procedure TForm1.FormCreate(Sender: TObject); var sStrings: TStrings; begin sStrings := TStringList.Create; {...} end; Um exemplo do que estou falando seria observar o comportamento da Classe TCustomR (Extctrls.pas), onde, o campo de armazenamento interno FItems declarado como TStrings observarmos o constructor do mesmo, podemos ver que FItems atribuda a uma ocorrncia de TStringList. A dica de TStrings x TStringList pode servir mais para os criadores de componentes! Diferena entre Objetos e Classes Um outro fato que eu vejo em alguns colegas, a dvida do que uma Classe, Um Objeto e at mesmo um Componente? Classes Classes so (pelo menos pense assim) como um Super Registro, onde podemos declarar e descrever mtodos, propriedades e campos. Quando declaramos uma classe em Delphi (como em quase toda linguagem de programao que conheo, seja: C#, C++, etc) definimos nveis diferentes de acesso aos dados contidos na classe, atravs de Private, Protected, Public, Published (ou a mesmo Automated). Uma classe (em Delphi) herda de outra classe, onde desta forma, herda todos os campos, mtodos e propriedades. Se no declaramos uma classe ancestral o Delphi automaticam coloca TObject como sendo a classe ancestral. Quando cito e falo em Referncias de Classes (citado algumas vezes nesse artigo) ela na realidade uma expresso que denomina uma classe especfica. Referncias de Classes so ponteiro para a tabela de informaes de tempo de execuo (VMT). Quando testamos uma classe com operador is (explicado acima) voc est testando a referncia de classe. Classes so sempre apenas para leitura e residem na memria de Leitura. Objetos Um objeto a instncia dinmica de uma classe. no objeto que podemos escrever e executar operaes, isto , Objetos no so apenas para Leitura conforme a Classe. Voc cria o objeto usando a referncia da classe, chamando o seu constructor. Exemplo: oObjeto := TMinhaClasse.Create;

J a referncia de Objeto o trecho de memria onde o Delphi armazena os valores para todos campos do Objeto, a referncia de objeto um ponteiro para o objeto. Quando criamos dinamicamente, somos os responsveis por liberar tal objeto, usando: oObjeto.Free; sempre envolto num bloco try...finally...end; o Delphi no possui coleta de Lixo automtica ( Collector) como acontece no .NET, JAVA, SmallTalk, etc. Componentes Explicar o que um componente o mais simples. Componente tudo aquilo (se falando em D esquea o COM - Component Object Model) que voc pode manipular num formulrio Delph componente tem que obrigatoriamente herdar da Classe TComponent no seu mais alto nvel ancestral. Concluso A inteno do artigo era apresentar algumas palavras usadas no dia a dia do Delphi do qual no tnhamos certeza de onde as mesmas vinham e como se comportavam. Espero ter esclarecido algumas dvidas e estou aberto sugesto e/ou troca de idias. Sucesso e Sade a todos! Um Abrao.
Sobre o Autor

Anderson Haertel Rodrigues - aka AHR Autor do Livro: Sistemas Multicamadas com Delphi - dbExpress e DataSnap Editora Visual Books -www.visualbooks.com.br anderson.hr@bol.com.br - anderson.hr@zipmail.com.br Florianpolis - Santa Catarina - Brasil