Ir para conteúdo
Fórum Script Brasil
  • 0

Curiosidade


Thales Pontes Martins

Pergunta

Eu acabei de responder o tópico "como transformar richedit em um bitmap", e eu disse para o rapaz igualar a propriedade Font do RichEdit e do Canvas ->

Canvas.Font:=RichEdit1.Font

Bom o tipo TFont é uma classe, portanto a expressão sizeof(Font) retorna 4, porque as classes são na verdade ponteiros para onde estão os dados, e ponteiros tem 4 bytes.

Pergunta: Quando você dá o comando Canvas.Font:=RichEdit.Font, ele apenas copia o ponteiro sendo que Canvas.Font passará a acessar os mesmos dados que RichEdit.Font, ou ele não mexe nos ponteiros e sim copia todas as propriedades e campos de uma classe pra outra?

Link para o comentário
Compartilhar em outros sites

5 respostass a esta questão

Posts Recomendados

  • 0
Pergunta: Quando você dá o comando Canvas.Font:=RichEdit.Font, ele apenas copia o ponteiro sendo que Canvas.Font passará a acessar os mesmos dados que RichEdit.Font, ou ele não mexe nos ponteiros e sim copia todas as propriedades e campos de uma classe pra outra?
Eu iria sugerir que fosse utilizado o método Assign para copiar as propriedades de um font em outro. Acho este o método mais apropriado.

Mas, após verificando a questão colocada em que poderia ocorrer de o ponteiro do primeiro passar a apontar para o segundo constatei que isso não ocorre. Ao menos, não para esta propriedade.

Fui, então, dar uma olhada no código fonte do TControls e constatei que quando você colocar a atribuição proposta, o método SetFont faz justamente o uso do Assign. Resumindo: Tanto faz utilizar o Assign ou atribuir a propriedade Font diretamente.

[]s

Link para o comentário
Compartilhar em outros sites

  • 0

Mas e quanto as outras classes?

então você está querendo dizer que na implementação de um classe eu posso implementar um método para ser executado quando houver a atribuição := ?????

e se não houver esse método, aí ocorre a cópia dos ponteiros????

Link para o comentário
Compartilhar em outros sites

  • 0
então você está querendo dizer que na implementação de um classe eu posso implementar um método para ser executado quando houver a atribuição := ?????
Sim. Aliás é assim que a maioria das propriedades de uma classe são setadas. Dê uma olhada na unit Controls (p.ex.).

A aplicação comum é como o exemplo abaixo:

type
  TTeste = Class
    constructor Create; virtual;
  protected
    FValor :Integer;  // define a variável protegida
    FNome :String;  
    FDate :TDate;
    procedure SetValor(Value :Integer);  / procedimento para atribuir o valor de FValor
    function GetValor :Integer;  // função para retornar o valor de FValor
    function GetData :TDate;  // função para retorna o valor de FData
    function GetDataAsString :String;  // função para retornar FData no formato string
  public
    property Valor :Integer read GetValor write SetValor;
    property Nome :String read FNome;
    property Data :TDate read GetData;
    property DataAsString :String read GetDataAsString;
  end;

constructor TTest.Create;
begin
  inherited;
  FValor := 0;  // inicialização da propriedade
  FNome := 'Teste';
  FData := Date;
end;

procedure TTest.SetValor(Value :Integer);
begin
  if Value <> FValor then
  begin
    FValor := Value;
   // faz outras coisas se necessário
  end;
end;

function TTest.GetValor :Integer;
begin
  Result := FValor;
end;

function TTest.GetData :TDate;
begin
  Result := FData;
end;

function TTest.GetDataAsString :String;
begin
  Result := DateToStr(FData);
end;
Daí no código do programa que utiliza a classe fica apenas assim:
var
  Teste :TTeste;
begin
  Teste := Teste.Create;
  Teste.Valor := 10;  // neste momento o método SetValor será chamado
  ShowMessage(IntToStr(Teste.Valor));  // Neste momento o método GetValor será chamado
  ShowMessage(Teste.Nome);  // Observe que Nome é apenas leitura
 // porque não foi definido um meio de atribuir-lhe um valor através da 
 // instrução [i]write [/i]na definição da propriedade.
  ShowMessage(Teste.GetDataAsString)  // observe que você pode definir propriedades
 // para retornar uma mesma variável da classe de forma diferente
  Teste.Free;
end;

e se não houver esse método, aí ocorre a cópia dos ponteiros????
Até onde sei, sim.

Quem sabe outros colegas possam colaborar...

[]s

Link para o comentário
Compartilhar em outros sites

  • 0

Obrigado por responder, Micheus. Mas eu acho que não entendeu bem a minha pergunta. A respeito dos métodos de leitura e gravação de propriedades eu já sabia, no caso do TFont esses métodos pertenceriam a TCanvas. Eu perguntei se a própria classe que será copiada pode ter um método de atribuição dela mesma, tipo ->

UmaClasse := OutraClasse;
Onde UmaClasse e OutraClasse não são propriedades de um componente, eu apenas declarei elas soltas no meu programa. Entendeu? Por exemplo ->
procedure Algo;
var list1, list2 : TStrings;
begin
  list1:=TStringList.Create;
  list2:=TStringList.Create;
  list1.add('Alguma Coisa');
  list2.add('Outra Coisa');
  list1:=list2;
end;

Oque irá acontecer quando eu der o comando list1:=list2; ?

Fiz um teste aqui e acabei de constatar que nesse caso somente os ponteiros são igualados. Isso explica todos os problemas que tive certa vez ao fazer um programa que trabalhava muito com TStrings, porque eu achava que funcionava da mesma forma que variáveis do tipo registro, ou seja, quando você atribui com := os dados são copiados de uma variável para outra, aí se você mudar uma a outra continua igual... Mas com classes, se você atribuir da meneira mostrada -> list1:=list2; tudo que você mudar numa muda na outra também, porque elas passam a ser a mesma. Nesse caso o método mais apropriado é o assign, não é mesmo?

Link para o comentário
Compartilhar em outros sites

  • 0

Desculpe, não ter entendido direito o seu questionamento. :rolleyes:

Mas com classes, se você atribuir da meneira mostrada -> list1:=list2; tudo que você mudar numa muda na outra também, porque elas passam a ser a mesma. Nesse caso o método mais apropriado é o assign, não é mesmo?
Exato. Como você mesmo já citou anteriormente, variáveis do "tipo classe" são ponteiros.

Embora eu não me lembre bem qual, mas, já tive a oportunide de utilizar o assign para algum outro tipo de compenente e não obtive o resultado esperado (isso porque talvez o assing não foi programado para fazer o que eu esperava que fizesse).

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...