Alguém aqui usa Lazarus?

na minha humilde opinião, a qtde de classes não vai afetar em nada isso. talvez a qtde de referencias poderia criar algum prob para os menos experientes.

eu uso OO, confesso q não desenvolvo preocupado se estou usando OO ou não.
desenvolvo procurando a melhor técnica do ponto de vista performance/manutenção
se OO for a melhor com certeza irei usá-la.

uso interfaces só qdo necessário. não gosto de usar só pra ver a palavra interface em negrito no meu código.

cite algumas situações em q eu poderia estar achando q estava desenvolvendo OO e q na realidade não o é.
qual a real dificuldade em usar interface no delphi?

e como ja supra citado, um exemplo real de q a ausência de GC comprometeria o desenvolvimento;

dá impressão de q suas classes são tdas dependentes umas das outras.
vc não usa encapsulamento, abstração, etc?
sábia q a razão de ser do OO é justamente evitar esse espaguete?

Sobre DBWare realmente o delphi é bom nisso. mas ser bom em algo não significa ser ruim em outros.
nem td é DBWare.

posso te mandar um exemplo de um programa desenvolvido em OO e q não tem nem um DBWare até pq ele não tem nada a ver com DB.

[quote=x@ndy]
Não entendi sua colocação? Todos os domínios devem ter uma hierarquia de classes é isso? Se for eu discordo de você, pois determinados domínios não representam hierarquisa de classes, pelo contrário, existe uma colaboração entre elas, mas nunca uma hierarquia. Pense em um sistema comercial, por exemplo, as muitas classes desse domínio não estão em uma hierarquia, ou até estão, mas pertencem a hierarquias distintas. Se eu usar um Owner isso vai me criar um grave problema, pois eu tenho classes distintas com período de vida distintos. Um outro caso são serviços! Nesse caso não posso contar com o fim da aplicação para liberar a memória! Na verdade já tive esse problema em um sistema assim. Muitas classes eram criadas e a sua memória não era devolvida e assim em alguns dias a memória do servidor era esgotada. Por isso que digo que isso deve ser usado com cuidado.[/quote]

X@andy, o grafo hierárquico que você vai criar em algum ponto vai possuir várias bifurcações e várias classes do mesmo nível terão como ancestral apenas TObject, QObject, ou Object como no caso do java, que já faz isso implicitamente. Esse é o desenho ideal.

E você também está confundindo compartilhamento de memória com herança, o que não tem nada a ver com reference counting. Se um pai(pai é quem compartilha e conta referencias) compartilha seu endereço de memória com os filhos(alocados em memória), se eu matar o pai os filhos morrem sem eu ter a necessidade de eu ter que fazer isso explicitamente (chamar delete ou free).

No caso da hierarquia e herança de classes, você já faz isso com java sem perceber, todas as suas classes herdam Object.

http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html

[quote=x@ndy][quote=juliocbq]
Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.[/quote]

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção![/quote]

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.

[quote=GilsonNunes]eu tenho servidores desenvolvidos em pascal e nunca tive problema com memoria não liberada.

qdo falei do Owner não disse q ele era “um”, mt menos disse q era “uma” hierarquia. disse q ele pode ser usado qdo conveniente.
dei o exemplo do formCheioDeControles q vc não tem q destruir cada controle. o Form seria o Owner deles, mas não de td o projeto.

do jeito q alguns falam parece impossível desenvolver sem GC. Realmente é impossível desenvolver se vc trabalhar no pascal como se tivesse trabalhando com java.

negocio é a pratica.

vamos pensar uma situação real q se tornaria mt dificil sem o GC.

os Objetos q precisam de outros pra se fazer algo, basta colocar na lista “para serem avisados”.
não herda de TComponent? o q seria? q tal usar uma cópia então? seria custoso?
q tal um q implementa uma especie de Share?

sobre a tal Hierarquia q seria criado pelo Owner, ou eu não entendi ou é isso?

o q um TDataSet tem a ver com TForm? e no entanto ele pode ser apropriado por ele.

vejo sempre alguem dizer: se vc destruir um Datamodule enquanto um form tiver usando ele?
pq vc iria destruir esse maldito? pra criar “quizumba”?

eu destruo DataModules. mas com certeza não vai ter nem um form usando ele.
como eu sei? pq não tem nenhuma variavel global recebendo a instancia dele pra um programador avacalhar a coisa.

OO no pascal funciona bem. se vc começar bem.

duas regras importantes:
Regra nº 1: Retornar uma nova instancia só se for construtor ou o metodo tiver um nome do tipo Criar, Novo, Etc.;
Regra nº 2: não esqueça a regra nº 1;

um exemplo da violação dessas regras: (quem diria, a VCL?)

forms.pas linha 5570;

function TCustomForm.GetFormImage: TBitmap; .. begin Result := TBitmap.Create; ...

ai um infeliz acha q ta no java e faz assim:

MeuForm.GetFormImage.SaveToFile(xxxx);
ou
Printer.Canvas.Draw(0, 0, MeuForm.GetFormImage);

a instania retornada por TBitmap.Create; ficou sobrando mais q jiló na janta.

como deveria ser então?

assim:

procedure TCustomForm.GetFormImage(Result : TBitmap); .. begin Result.Width := ClientWidth; Result.Height := ClientHeight; Result.Canvas.Brush := Brush; Result.Canvas.FillRect(ClientRect); Result.Canvas.Lock; try if GetWindowLong(Handle, GWL_STYLE) and WS_BORDER <> 0 then Ofs := -1 // Don't draw form border else Ofs := 0; // There is no border PaintTo(Result.Canvas.Handle, Ofs, Ofs); finally Result.Canvas.Unlock; end; ...

pq ai o cara percebia logo q não tava no eclipse.

[/quote]

Justamente. É que a conversa desviou para herança e acabamos fazendo confusão com isso e contagem de referências.

[quote=x@ndy]Gilson, como tu trabalha em teus projetos? Usa interface Inteligente, no modo tradicional do Delphi, usando DBware, Ou cria uma classe para cada entidade nos teus sistemas?
Digo isso, por que vejo que você não tem muita experiência com sistemas totalmente OO. Suas colocações são válidas, mas são colocações de quem nunca enfrentou os problemas trazidos por um sistema totalmente OO com uma dezena, ou até centena de classes. Pelo que vejo você deve fazer o que eu fiz durante muito tempo, você usa objetos em seus projetos mas não desenvolve orientado a objetos.

Como disse antes, existe uma forma de contornar o problema das referencias no delphi, principalmente usando contagem de referencia, mas isso torna o desenvolvimento mais complexo e sujeito a erros, se fazermos através de notificações, isso se torna ainda mais complexo e mais sujeitos a erros ainda. Quando usamos poucas classes em nossos sistemas é fácil controlar isso porém a media que o número de classes cresce isso muda de figura. Esquecer de uma implementar isso em algum lugar gera erros dificeis de localizar.

Outro problema é a abordagem do delphi no uso de interfaces. Qualquer sistema OO faz uso intensivo de interfaces. Agora quem já criou interfaces no Delphi sabe as dificuldades de o faze-lo.

Como disse antes, delphi é muito bom, mas não é a ferramenta ideal para desenvolver um sistema OO, porém é a melhor ferramenta para usar DBware.

[/quote]

Não existe dificuldade nenhuma de usar interfaces com o delphi. É a mesma coisa que usar java ou c++. No caso da c++ a interface é apenas uma classe pura abstrata com métodos x=0
em pascal é isso. A idéia é sempre a mesma, o que muda é sintaxe.

[code]type

IColor = Interface(IInterface)

 function getRed : Boolean;

 property IsRed : Boolean read getRed;

end;[/code]

[quote=juliocbq][quote=x@ndy]
Não entendi sua colocação? Todos os domínios devem ter uma hierarquia de classes é isso? Se for eu discordo de você, pois determinados domínios não representam hierarquisa de classes, pelo contrário, existe uma colaboração entre elas, mas nunca uma hierarquia. Pense em um sistema comercial, por exemplo, as muitas classes desse domínio não estão em uma hierarquia, ou até estão, mas pertencem a hierarquias distintas. Se eu usar um Owner isso vai me criar um grave problema, pois eu tenho classes distintas com período de vida distintos. Um outro caso são serviços! Nesse caso não posso contar com o fim da aplicação para liberar a memória! Na verdade já tive esse problema em um sistema assim. Muitas classes eram criadas e a sua memória não era devolvida e assim em alguns dias a memória do servidor era esgotada. Por isso que digo que isso deve ser usado com cuidado.[/quote]

X@andy, o grafo hierárquico que você vai criar em algum ponto vai possuir várias bifurcações e várias classes do mesmo nível terão como ancestral apenas TObject, QObject, ou Object como no caso do java, que já faz isso implicitamente. Esse é o desenho ideal.

E você também está confundindo compartilhamento de memória com herança, o que não tem nada a ver com reference counting. Se um pai(pai é quem compartilha e conta referencias) compartilha seu endereço de memória com os filhos(alocados em memória), se eu matar o pai os filhos morrem sem eu ter a necessidade de eu ter que fazer isso explicitamente (chamar delete ou free).

No caso da hierarquia e herança de classes, você já faz isso com java sem perceber, todas as suas classes herdam Object.

http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html[/quote]
Não é isso! Não estou falando de hierarquia de herança, acho que a palavara hierarquia ficou confusa aqui. O que queria falar é que podemos ter uma espécie de escada de objetos, vamos a um exemplo. Digamos que tenha-mos as classes A, B, C, D e eu faça
A.Create(nil)
B.Create(A)
C.Create(B)
D.Create©

Para que a memória dos objetos sejam liberaradas eu tenho que destruir o objeto A, até ai tudo bem, porém, se por engano eu destruo o objeto B, a memória de todos os objetos sera liberada, digo, a memória de todos os obetos que tem o B como owner e eu perco a referência a eles. Por isso que eu disse que isso tem que ser usado com cuidado. E essa hierarquia de que falo. Ao usar o Owner para liberar a memória temos que ter cuidado para não criar algo desse tipo!

[quote=juliocbq][quote=x@ndy][quote=juliocbq]
Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.[/quote]

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção![/quote]

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.[/quote]

Não entendi como isso funciona, poderia me explicar?

[quote=x@ndy][quote=juliocbq][quote=x@ndy][quote=juliocbq]
Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.[/quote]

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção![/quote]

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.[/quote]

Não entendi como isso funciona, poderia me explicar?[/quote]

Porque essa classe já implementa reference count.
http://www.freepascal.org/docs-html/rtl/system/tinterfacedobject.html

Eu disse isso por que usar interfaces no java é muito simples e no delphi a pessoa tem que saber como a interface funciona, vamos a um exemplo usando a sua interface
Se eu fizer isso, como faria no java, vai gerar uma exceção

type TTesteColor = class(IColor) function getRed : Boolean; property IsRed : Boolean read getRed; end;Pois a interface exige a implementação dos métodos

function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall;
Então ou implemento isso em todas as classes ou faço isso.

type TTesteColor = class(TInterfacedObject, IColor) function getRed : Boolean; property IsRed : Boolean read getRed; end;Até ai tudo bem, mas o pior é que o cuidado que temos que ter para não misturar ponteiros para objetos com ponteiros para interfaces de modo a não termos problema, veja aqui: http://br.groups.yahoo.com/group/delphi-br/message/196124

[quote=x@ndy][quote=juliocbq][quote=x@ndy]
Não entendi sua colocação? Todos os domínios devem ter uma hierarquia de classes é isso? Se for eu discordo de você, pois determinados domínios não representam hierarquisa de classes, pelo contrário, existe uma colaboração entre elas, mas nunca uma hierarquia. Pense em um sistema comercial, por exemplo, as muitas classes desse domínio não estão em uma hierarquia, ou até estão, mas pertencem a hierarquias distintas. Se eu usar um Owner isso vai me criar um grave problema, pois eu tenho classes distintas com período de vida distintos. Um outro caso são serviços! Nesse caso não posso contar com o fim da aplicação para liberar a memória! Na verdade já tive esse problema em um sistema assim. Muitas classes eram criadas e a sua memória não era devolvida e assim em alguns dias a memória do servidor era esgotada. Por isso que digo que isso deve ser usado com cuidado.[/quote]

X@andy, o grafo hierárquico que você vai criar em algum ponto vai possuir várias bifurcações e várias classes do mesmo nível terão como ancestral apenas TObject, QObject, ou Object como no caso do java, que já faz isso implicitamente. Esse é o desenho ideal.

E você também está confundindo compartilhamento de memória com herança, o que não tem nada a ver com reference counting. Se um pai(pai é quem compartilha e conta referencias) compartilha seu endereço de memória com os filhos(alocados em memória), se eu matar o pai os filhos morrem sem eu ter a necessidade de eu ter que fazer isso explicitamente (chamar delete ou free).

No caso da hierarquia e herança de classes, você já faz isso com java sem perceber, todas as suas classes herdam Object.

http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html[/quote]
Não é isso! Não estou falando de hierarquia de herança, acho que a palavara hierarquia ficou confusa aqui. O que queria falar é que podemos ter uma espécie de escada de objetos, vamos a um exemplo. Digamos que tenha-mos as classes A, B, C, D e eu faça
A.Create(nil)
B.Create(A)
C.Create(B)
D.Create©

Para que a memória dos objetos sejam liberaradas eu tenho que destruir o objeto A, até ai tudo bem, porém, se por engano eu destruo o objeto B, a memória de todos os objetos sera liberada e eu perco a referência a eles. Por isso que eu disse que isso tem que ser usado com cuidado. E essa hierarquia de que falo. Ao usar o Ower para liberar a memória temos que ter cuidado para não criar algo desse tipo![/quote]

Isso é verdade. Se o pai exclui o endereço que os filhos apontam você pode ter problemas. Além do mais, existem algoritmos que cuidam disso.

O Implicit sharing é um mecanismo um pouco diferente e bem robusto. Ele já consegue cuidar desse problema que você citou. Nunca cometi nenhum deslize usando o qt dessa maneira.

Removi esse tópico pois repliquei algo que eu mesmo havia colocado

[quote=juliocbq][quote=x@ndy][quote=juliocbq][quote=x@ndy][quote=juliocbq]
Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.[/quote]

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção![/quote]

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.[/quote]

Não entendi como isso funciona, poderia me explicar?[/quote]

Porque essa classe já implementa reference count.
http://www.freepascal.org/docs-html/rtl/system/tinterfacedobject.html[/quote]
Ah sim! Mas isso cria um outro problema: http://br.groups.yahoo.com/group/delphi-br/message/196124

Pessoal, o que estou colocando aqui não é que impossível de se fazer um sistema OO no Delphi, por que não é. O que coloco é que ele não é linguagem mais adequada para isso, pois impõem uma serie de cuidados a serem tomados.
Pela discussão até levada até aqui é fácil notar que para se fazer isso em Delphi é necessário um bom conhecimento de como ele funciona, se não você vai ter diversos problemas.
Digo isso por que já enfrentei esses problemas. Esses problemas se tornam mais evidentes ainda quando se tem uma equipe formadas de programadores pleno/junior.

O próprio exemplo que você colocou do FreeNotification mostra a utlização de objetos, mas não uma programação orientada a objetos!

Já citei isso aqui duas vezes, mas vai de novo:http://br.groups.yahoo.com/group/delphi-br/message/196124

Eu nunca falei que ausência de Garbage Colector compremete o desenvolvimento. O que estou falando é que ele dificulta o desenvolvimento! Já disse antes e vou falar de novo, você pode programar OO no delphi, não existe uma restrição, porém você terá que contornar a falta do GC e terá que ter cuidado no uso de interfaces. No resto use e seja feliz.

viu? é só uma questão de saber. vc deu dois exemplos o segundo tentou melhorar mas realmente ficou ruim comparando com java.

ma e o tercerio exemplo?

faltou ele: ele era o correto:

[code]unit Unit1;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls;

type

IRotulavel = interface
function GetTexto : string;
function GetDesenvolvedor : string;
end;

{ Botao }

{ TBotao }

TBotao = Class(TButton, IRotulavel)
public
function GetTexto: string;
function GetDesenvolvedor: string;
end;

{ TGShape }

TGShape = Class(TShape, IRotulavel)
public
function GetTexto: string;
function GetDesenvolvedor: string;
end;

{ TForm1 }

TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
procedure BotaoClick(Sender: TObject);
procedure ShapeClick(Sender: TObject);
public
{ public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

{ TBotao }

function TBotao.GetTexto: string;
begin
Result := 'Botão: '+Caption;
end;

function TBotao.GetDesenvolvedor: string;
begin
Result := ‘Gilson’;
end;

{ TGShape }

function TGShape.GetTexto: string;
begin
Result := 'Shape: ’ + ColorToString(Brush.Color);
end;

function TGShape.GetDesenvolvedor: string;
begin
Result := ‘João’;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Tag := Tag + 1;
if Button = mbLeft then
begin
with TBotao.Create(Self) do
begin
Parent := Self;
Top:=Y;
Left:=X;
OnClick:=@BotaoClick;
Caption:=IntToStr(Self.Tag);
end;
end else
begin
with TGShape.Create(Self) do
begin
Parent := Self;
Top:=Y;
Left:=X;
OnClick:=@ShapeClick;
Brush.Color:= RGBToColor(Self.Tag * 10, Self.Tag * 40, Self.Tag * 80);
end;
end;
end;

procedure MostraTexto(obj : IRotulavel);
begin
ShowMessage(obj.GetTexto+#13#10’Feito por: '+obj.GetDesenvolvedor);
end;

procedure TForm1.BotaoClick(Sender: TObject);
begin
MostraTexto(Sender as TBotao);
end;

procedure TForm1.ShapeClick(Sender: TObject);
begin
MostraTexto(Sender as TGShape);
end;

end.
[/code]

esse é um exemplo de uso de inteface, não?
no java teria q facilidade a mais?

[quote=GilsonNunes][quote=x@ndy]
Eu disse isso por que usar interfaces no java é muito simples e no delphi a pessoa tem que saber como a interface funciona, vamos a um exemplo usando a sua interface
Se eu fizer isso, como faria no java, vai gerar uma exceção

type TTesteColor = class(IColor) function getRed : Boolean; property IsRed : Boolean read getRed; end;Pois a interface exige a implementação dos métodos

   function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
   function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;[/code]
Então ou implemento isso em todas as classes ou faço isso.

[code]type
   TTesteColor = class(TInterfacedObject, IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;[/code]Pois a interface exige a implementação dos métodos
Até ai tudo bem, mas o pior é que o cuidado que temos que ter para não misturar ponteiros para objetos com ponteiros para interfaces de modo a não termos problema, veja aqui: [url]http://br.groups.yahoo.com/group/delphi-br/message/196124[/url]
[/quote]

viu? é só uma questão de saber. vc deu dois exemplos o segundo tentou melhorar mas realmente ficou ruim comparando com java.

ma e o tercerio exemplo?

faltou ele: ele era o correto:

[code]unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

   IRotulavel = interface
      function GetTexto : string;
      function GetDesenvolvedor : string;
   end;

   { Botao }

   { TBotao }

   TBotao = Class(TButton, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;

   { TGShape }

   TGShape = Class(TShape, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;


  { TForm1 }

  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    procedure BotaoClick(Sender: TObject);
    procedure ShapeClick(Sender: TObject);
  public
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation

{$R *.lfm}

{ TForm1 }

{ TBotao }

function TBotao.GetTexto: string;
begin
  Result := 'Botão: '+Caption;
end;

function TBotao.GetDesenvolvedor: string;
begin
  Result := 'Gilson';
end;

{ TGShape }

function TGShape.GetTexto: string;
begin
  Result := 'Shape: ' + ColorToString(Brush.Color);
end;

function TGShape.GetDesenvolvedor: string;
begin
  Result := 'João';
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Tag := Tag + 1;
  if Button = mbLeft then
  begin
    with TBotao.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@BotaoClick;
      Caption:=IntToStr(Self.Tag);
    end;
  end else
  begin
    with TGShape.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@ShapeClick;
      Brush.Color:= RGBToColor(Self.Tag * 10, Self.Tag * 40, Self.Tag * 80);
    end;
  end;
end;

procedure MostraTexto(obj : IRotulavel);
begin
  ShowMessage(obj.GetTexto+#13#10'Feito por: '+obj.GetDesenvolvedor);
end;

procedure TForm1.BotaoClick(Sender: TObject);
begin
   MostraTexto(Sender as TBotao);
end;

procedure TForm1.ShapeClick(Sender: TObject);
begin
   MostraTexto(Sender as TGShape);
end;

end.

esse é um exemplo de uso de inteface, não?
no java teria q facilidade a mais?
[/quote]
Qual a diferença desse exemplo para o anterior? Parece que você esta querendo confundir, até porque (se não me engano), TComponent, já herda de TInterfacedObject que implementa os métodos. O que você fez, foi algo assim:

type TColorBase = class(TInterfacedObject) end; ... type TTesteColor = class(TColorBase, IColor) function getRed : Boolean; property IsRed : Boolean read getRed; end;
Qual a diferença do seu exemplo afinal? Tirando o fato de você colocar a implementação também?
E pelo que eu vejo, você não leu o que estava no link, então vou copiar e colar aqui:

[quote]Re: [delphi-br] Problema com Objetos da classe TInterfacedObject + uma interface

PUBLICIDADE
2008/12/29 Thales (Shubacca) - Tebo Software <tebosoftware@…>:

O problema que estou encontrando é que após o dao persistir o objeto, ele
chama o destructor do objeto persistido, mas eu não destrui o mesmo.

Debugando descobri que o campo que conta as referencias do objeto fica com
valor 0 (zero) após a persistencia, mas ainda existe uma variavel local que
está fazendo referencia ao meu objeto.

alguém sabe como me ajudar nisso?

Parece que você está misturando ponteiros para objetos e ponteiros
para interface. O gerenciamento de memória do Delphi, no que tange
interfaces, é feito com contagem de referência: associação conta mais
um, alteração do ponteiro ou saída de escopo conta menos um. Mas se
você faz com que um ponteiro para objeto aponte para objetos que
também tem interfaces apontando, tão logo as interfaces saiam de
escopo e o objeto será destruído, deixando aquele ponteiro
referenciando uma área de memória inválida. Mais ou menos assim:

var
VObjI: IObj; // interface
VObjO: TObj; // TObj implementa IObj
begin
VObjO := TObj.Create;
VObjI := VObjO;
VObjI := nil;
VObjO.Free; // erro
end;

Caso o problema seja este, então ou você não mistura ponteiros para
objeto com ponteiros para interface, ou contorna da mesma forma que eu
contornei:
http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html

Se não for, detalhe melhor a sua implementação.


Joao Morais[/quote]

[quote=x@ndy][quote=juliocbq][quote=x@ndy][quote=juliocbq][quote=x@ndy][quote=juliocbq]
Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.[/quote]

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção![/quote]

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.[/quote]

Não entendi como isso funciona, poderia me explicar?[/quote]

Porque essa classe já implementa reference count.
http://www.freepascal.org/docs-html/rtl/system/tinterfacedobject.html[/quote]
Ah sim! Mas isso cria um outro problema: http://br.groups.yahoo.com/group/delphi-br/message/196124[/quote]

É justamente o que o link que você postou disse. Se você já tem o smart pointer não precisa gerenciar memória manualmente para não causar confusão.

eu precisei implemntar os tais metodos q vc citou?

[quote]
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall; [/quote]

herdei de TInterfacedobject?

o cara ai do tal link ta tendo problema pq ele usa o q conta referencia e trata como se não fosse. (é o tipico despreparado)

mas vc não viu nada de diferente no exemplo q postei?
vc então não leu ele.

mas faz o seguinte:

crie um exemplo usando inteface no java e poste aki pra vermos como ficaria em pascal.
blz?

[quote=x@ndy]
Bom, vejo que você não leu o que estava no link, então vou colocar aqui:

[quote]Re: [delphi-br] Problema com Objetos da classe TInterfacedObject + uma interface

PUBLICIDADE
2008/12/29 Thales (Shubacca) - Tebo Software <tebosoftware@…>:

O problema que estou encontrando é que após o dao persistir o objeto, ele
chama o destructor do objeto persistido, mas eu não destrui o mesmo.

Debugando descobri que o campo que conta as referencias do objeto fica com
valor 0 (zero) após a persistencia, mas ainda existe uma variavel local que
está fazendo referencia ao meu objeto.

alguém sabe como me ajudar nisso?

Parece que você está misturando ponteiros para objetos e ponteiros
para interface. O gerenciamento de memória do Delphi, no que tange
interfaces, é feito com contagem de referência: associação conta mais
um, alteração do ponteiro ou saída de escopo conta menos um. Mas se
você faz com que um ponteiro para objeto aponte para objetos que
também tem interfaces apontando, tão logo as interfaces saiam de
escopo e o objeto será destruído, deixando aquele ponteiro
referenciando uma área de memória inválida. Mais ou menos assim:

var
VObjI: IObj; // interface
VObjO: TObj; // TObj implementa IObj
begin
VObjO := TObj.Create;
VObjI := VObjO;
VObjI := nil;
VObjO.Free; // erro
end;

Caso o problema seja este, então ou você não mistura ponteiros para
objeto com ponteiros para interface, ou contorna da mesma forma que eu
contornei:
http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html

Se não for, detalhe melhor a sua implementação.


Joao Morais[/quote][/quote]

O que foi postado no link é que você não precisa chamar free explicitamente porque já usa contagem de referência. Aliás, fazer isso é a mesma coisa que querer usar um delete num objeto java.
Vocês estão colocando posts muito extensos. Tá ficando difícil de ler.

Para criar software bem modelado não é necessário usar uma linguagem como java. Nem de longe java facilita nesse quesito. Existem implementações em c++ e pascal que dão um banho em muitas que são produzidas em linguagens modernas. Um exemplo disso é o proprio qt. Totalmente MVC.

Para construir software bom você tem que saber o que faz com as ferramentas que utiliza.

[quote=x@ndy][quote=GilsonNunes][quote=x@ndy]
Eu disse isso por que usar interfaces no java é muito simples e no delphi a pessoa tem que saber como a interface funciona, vamos a um exemplo usando a sua interface
Se eu fizer isso, como faria no java, vai gerar uma exceção

type TTesteColor = class(IColor) function getRed : Boolean; property IsRed : Boolean read getRed; end;Pois a interface exige a implementação dos métodos

   function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
   function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;[/code]
Então ou implemento isso em todas as classes ou faço isso.

[code]type
   TTesteColor = class(TInterfacedObject, IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;[/code]Pois a interface exige a implementação dos métodos
Até ai tudo bem, mas o pior é que o cuidado que temos que ter para não misturar ponteiros para objetos com ponteiros para interfaces de modo a não termos problema, veja aqui: [url]http://br.groups.yahoo.com/group/delphi-br/message/196124[/url]
[/quote]

viu? é só uma questão de saber. vc deu dois exemplos o segundo tentou melhorar mas realmente ficou ruim comparando com java.

ma e o tercerio exemplo?

faltou ele: ele era o correto:

[code]unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

   IRotulavel = interface
      function GetTexto : string;
      function GetDesenvolvedor : string;
   end;

   { Botao }

   { TBotao }

   TBotao = Class(TButton, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;

   { TGShape }

   TGShape = Class(TShape, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;


  { TForm1 }

  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    procedure BotaoClick(Sender: TObject);
    procedure ShapeClick(Sender: TObject);
  public
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation

{$R *.lfm}

{ TForm1 }

{ TBotao }

function TBotao.GetTexto: string;
begin
  Result := 'Botão: '+Caption;
end;

function TBotao.GetDesenvolvedor: string;
begin
  Result := 'Gilson';
end;

{ TGShape }

function TGShape.GetTexto: string;
begin
  Result := 'Shape: ' + ColorToString(Brush.Color);
end;

function TGShape.GetDesenvolvedor: string;
begin
  Result := 'João';
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Tag := Tag + 1;
  if Button = mbLeft then
  begin
    with TBotao.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@BotaoClick;
      Caption:=IntToStr(Self.Tag);
    end;
  end else
  begin
    with TGShape.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@ShapeClick;
      Brush.Color:= RGBToColor(Self.Tag * 10, Self.Tag * 40, Self.Tag * 80);
    end;
  end;
end;

procedure MostraTexto(obj : IRotulavel);
begin
  ShowMessage(obj.GetTexto+#13#10'Feito por: '+obj.GetDesenvolvedor);
end;

procedure TForm1.BotaoClick(Sender: TObject);
begin
   MostraTexto(Sender as TBotao);
end;

procedure TForm1.ShapeClick(Sender: TObject);
begin
   MostraTexto(Sender as TGShape);
end;

end.

esse é um exemplo de uso de inteface, não?
no java teria q facilidade a mais?
[/quote]
Qual a diferença desse exemplo para o anterior? Parece que você esta querendo confundir, até porque (se não me engano), TComponent, já herda de TInterfacedObject que implementa os métodos. O que você fez, foi algo assim:

type TColorBase = class(TInterfacedObject) end; ... type TTesteColor = class(TColorBase, IColor) function getRed : Boolean; property IsRed : Boolean read getRed; end;
Qual a diferença do seu exemplo afinal? Tirando o fato de você colocar a implementação também?
E pelo que eu vejo, você não leu o que estava no link, então vou copiar e colar aqui:

[quote]Re: [delphi-br] Problema com Objetos da classe TInterfacedObject + uma interface

PUBLICIDADE
2008/12/29 Thales (Shubacca) - Tebo Software <tebosoftware@…>:

O problema que estou encontrando é que após o dao persistir o objeto, ele
chama o destructor do objeto persistido, mas eu não destrui o mesmo.

Debugando descobri que o campo que conta as referencias do objeto fica com
valor 0 (zero) após a persistencia, mas ainda existe uma variavel local que
está fazendo referencia ao meu objeto.

alguém sabe como me ajudar nisso?

Parece que você está misturando ponteiros para objetos e ponteiros
para interface. O gerenciamento de memória do Delphi, no que tange
interfaces, é feito com contagem de referência: associação conta mais
um, alteração do ponteiro ou saída de escopo conta menos um. Mas se
você faz com que um ponteiro para objeto aponte para objetos que
também tem interfaces apontando, tão logo as interfaces saiam de
escopo e o objeto será destruído, deixando aquele ponteiro
referenciando uma área de memória inválida. Mais ou menos assim:

var
VObjI: IObj; // interface
VObjO: TObj; // TObj implementa IObj
begin
VObjO := TObj.Create;
VObjI := VObjO;
VObjI := nil;
VObjO.Free; // erro
end;

Caso o problema seja este, então ou você não mistura ponteiros para
objeto com ponteiros para interface, ou contorna da mesma forma que eu
contornei:
http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html

Se não for, detalhe melhor a sua implementação.


Joao Morais[/quote][/quote]

Complementando:

No java é mais simples pois, só faço assim:

public interface Lutador { public boolean estaVivo(); public int forcaDeAtaque(); public String nome(); public int numeroDeVidasAtual(); public void registrarObservador(ObservadorDaLuta observador); } ... public class Inimigo implements Lutador { ... }