ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Constructor Create em class(TPersistent) [Resolvido]

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
tiagoshimizu
Membro Junior
Membro Junior


Registrado: Segunda-Feira, 28 de Setembro de 2009
Mensagens: 329

MensagemEnviada: Qui Mai 17, 2012 9:26 pm    Assunto: Constructor Create em class(TPersistent) [Resolvido] Responder com Citação

Olá pessoal. Estou com um projeto em que em uma unit tenho o seguinte código:
Código:

type
{$METHODINFO ON}
  TContasReceber = class(TPersistent)
  public
  destructor Destroy; override;
end;

constructor TContasReceber.Create;
begin
  inherited Create;
end;

destructor TContasReceber.Destroy;
begin
  inherited Destroy;
end;

Tipo, funciona legal ele só que estava precisando implementar uma rotina no Create e daí fui perceber que ele está alí só de enfeite!
Tipo, tentei debugar a aplicação e percebi que nem passa por ele! Fiz a mesma coisa com o destructor e por ele passa! Tentei colocar o override; porem me deu o erro que não se pode implementar o override; pois o constructor não é do tipo virtual. Teria alguma maneira de fazer ele passar pelo create?
Obrigado.


Editado pela última vez por tiagoshimizu em Qui Set 27, 2012 9:41 pm, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
felipecaputo
Colaborador
Colaborador


Registrado: Quinta-Feira, 13 de Mai de 2010
Mensagens: 1719
Localização: Florianópolis / SC

MensagemEnviada: Sex Mai 18, 2012 8:55 am    Assunto: Responder com Citação

Olá, para sobrescrever métodos não virtuais você pode utilizar o reintroduce;

Código:
type
{$METHODINFO ON}
  TContasReceber = class(TPersistent)
  public
    constructor Create; reintroduce;
    destructor Destroy; override;
end;

constructor TContasReceber.Create;
begin
  inherited Create;
end;

destructor TContasReceber.Destroy;
begin
  inherited Destroy;
end;



mas classes descendentes de TPersistent não precisam de override eu acho. Basta declarar o constructor que estava faltando no public e excrever o seu código dentro do create da sua classe

Código:
type
{$METHODINFO ON}
  TContasReceber = class(TPersistent)
  public
    constructor Create;
    destructor Destroy; override;
end;

constructor TContasReceber.Create;
begin
  inherited Create;
end;

destructor TContasReceber.Destroy;
begin
  inherited Destroy;
end;


tenho um artigo que diz algumas coisas sobre, se quiser conferir http://certificacaodelphi.somee.com/Artigos/artigoVer.aspx?id=17
_________________
if Post.State = psResolvido then
Post.Caption := Post.Caption + ' [RESOLVIDO]';
_____________________________________________
O único homem que está isento de erros, é aquele que não arrisca acertar. Albert Einstein
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail Visitar a homepage do Usuário MSN Messenger
tiagoshimizu
Membro Junior
Membro Junior


Registrado: Segunda-Feira, 28 de Setembro de 2009
Mensagens: 329

MensagemEnviada: Sex Mai 18, 2012 10:51 am    Assunto: Responder com Citação

felipecaputo, obrigado primeiramente pela resposta. A questão da falta do constructor na clausula public foi falha minha na hora de possar o código para o forum... Também, já havia tentado incluir o reintroduce e não adiantou. Continua não passando pelo create ao debugar!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
felipecaputo
Colaborador
Colaborador


Registrado: Quinta-Feira, 13 de Mai de 2010
Mensagens: 1719
Localização: Florianópolis / SC

MensagemEnviada: Sex Mai 18, 2012 10:59 am    Assunto: Responder com Citação

como o objeto está sendo criado? qual o tipo da variavel que o cria?

os fontes estão no mesmo pacote ou é um pacote diferente e importado apra a aplicação?
_________________
if Post.State = psResolvido then
Post.Caption := Post.Caption + ' [RESOLVIDO]';
_____________________________________________
O único homem que está isento de erros, é aquele que não arrisca acertar. Albert Einstein
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail Visitar a homepage do Usuário MSN Messenger
JCMF
Profissional
Profissional


Registrado: Quarta-Feira, 28 de Abril de 2010
Mensagens: 578
Localização: Recife, PE

MensagemEnviada: Sex Mai 18, 2012 11:02 am    Assunto: Responder com Citação

Bom dia amigo!

Sempre que vc for herdar uma classe, os métodos da superclasse, quando permitidos, podem ou devem ser sobrescritos.

O "reintroduce" não é diferente disso... ele apenas determina que a classe final vai possuir uma assinatura diferente da que existe na superclasse, mas o método da superclasse precisa estar marcado para isso, com virtual ou dynamic.

No seu exempo, a superclasse TPersistent herda diretamente de TObject e o construtor Create de TObject não possui implementação alguma e não é virtual ou dynamic. Isso indica que qualquer classe herdada de TObject, direta ou indiretamente, terá o construtor padrão.

Mesmo que você coloque um override ou reintroduce e aplique a palavra reservada inherited no seu construtor Create, nada será feito pois não existe implementação do método na superclasse.


Pelo que vejo, o problema está na sua classe que herda de TPersistent. Pelo Wiki da Embarcadero, isso não é aconselhável:

Citação:
O texto original: "Do not create instances of TPersistent. Use TPersistent as a base class when declaring objects that are not components, but that need to be saved to a stream or have their properties assigned to other objects."

Traduzido: "Não criar instâncias de TPersistent. Use TPersistent como uma classe base ao declarar objetos que não são componentes, mas que precisam ser salvos em um stream ou ter suas propriedades atribuídas a outros objetos."


A idéia é que a classe TPersistent, e através da sua declaração, para todos os objetos herdados de TObject, não seja instânciada e sim herdada por outras classes.



PS.: Para lhe ajudar nesse sentido, o Delphi disponibiliza dois métodos virtuais na classe TObject, e que estão disponíveis para todas as subclasses, que podem resolver o seu problema. Eles trabalham antes e após a criação padrão e devem ser declarados no nível mais alto de visibilidade "public":

procedure AfterConstruction; virtual;
procedure BeforeDestruction; virtual;



Espero ter ajudado.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
tiagoshimizu
Membro Junior
Membro Junior


Registrado: Segunda-Feira, 28 de Setembro de 2009
Mensagens: 329

MensagemEnviada: Sex Mai 18, 2012 11:07 am    Assunto: Responder com Citação

Hummm, entendi. Tipo, no caso então teria de criar uma nova unit "TBase" em que implementaria o constructor Create; herdando este do TPersistent e essa minha unit "TContasReceber" herdando da nova "TBase". Isso?
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
JCMF
Profissional
Profissional


Registrado: Quarta-Feira, 28 de Abril de 2010
Mensagens: 578
Localização: Recife, PE

MensagemEnviada: Sex Mai 18, 2012 11:13 am    Assunto: Responder com Citação

tiagoshimizu escreveu:
Hummm, entendi. Tipo, no caso então teria de criar uma nova unit "TBase" em que implementaria o constructor Create; herdando este do TPersistent e essa minha unit "TContasReceber" herdando da nova "TBase". Isso?


A idéia seria mais ou menos isso sim amigo!

TPersistent não vai ter override ou reintroduce no seu construtor Create e nem poderá chamar inherited pois não existe implementação na superclasse.

Mas a sua nova classe TBase, por exemplo, poderá ter um construtor Create que será virtual ou dynamic e todos que herdarem direta ou indiretamente dela pode ou deve dar override ou reintroduce do método para novas implementações.

Lembrando que:

override -> Sobrescreve o método da superclasse no seu formato original (Oq muda é a implementação do método)

reintroduce -> Sobrescreve o método da superclasse com alteração da sua assinatura (Mudam a assinatura e a implementação do método)
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
JCMF
Profissional
Profissional


Registrado: Quarta-Feira, 28 de Abril de 2010
Mensagens: 578
Localização: Recife, PE

MensagemEnviada: Sex Mai 18, 2012 11:22 am    Assunto: Responder com Citação

Uma dica boa para estudar implementações de classes do Delphi é acessar sua definição. Isso é possível quando se clica com o botão esquerdo do mouse em cima do nome da classe com a tecla CTRL pressionada.

Isso faz com que o delphi abra a definição da classe e assim, vc poderá ir navegando de classe em classe, subindo para a definição inicial de superclasse e estudar seu comportamento do começo ao fim.

Segurando a tecla CTRL;
Posiciona a seta do mouse no nome da classe que se deseja estudar;
Clica com o botão esquerdo do mouse;
Solta a tecla CTRL.

Fica a dica.


Espero ter ajudado.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
tiagoshimizu
Membro Junior
Membro Junior


Registrado: Segunda-Feira, 28 de Setembro de 2009
Mensagens: 329

MensagemEnviada: Sex Mai 18, 2012 11:23 am    Assunto: Responder com Citação

Bom, vamos lá. Criei a nova Unit "BAse" contendo a "TBase" da seguinte forma:

Código:
unit Base;

interface

uses Classes;

type
  TBase = class(TPersistent)
  public
    constructor Create; virtual;
    destructor Destroy; override;
  end;

implementation

{ TBase }

constructor TBase.Create;
begin
  inherited Create;
end;

destructor TBase.Destroy;
begin

  inherited Destroy;
end;

end.


Despois, na minha unit que contem o "TContasReceber" coloquei assim:
Código:

uses Classes,...., Base;

type
{$METHODINFO ON}
  TContasReceber = class(TBase)
  private
    constructor Create; override;
    destructor Destroy; override;
end;

constructor TContasReceber.Create;
begin
  inherited Create;
  ShowMessage('Agora sim!');
end;

destructor TContasReceber.Destroy;
begin
  inherited Destroy;
end;


Mas também não passou pelo create não!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
JCMF
Profissional
Profissional


Registrado: Quarta-Feira, 28 de Abril de 2010
Mensagens: 578
Localização: Recife, PE

MensagemEnviada: Sex Mai 18, 2012 2:45 pm    Assunto: Responder com Citação

Boa tarde amigo.

Não sei exatamente oq vc está pretendendo fazer com isso mas, aqui vai algumas explicações sobre o código que vc postou como exemplo:

A nova classe TBase, que está herdando de TPersistent:
Não deve executar o inherited no seu construtor Create pois a superclasse, além de não permitir tal coisa, não possui implementação em seu método.

Perceba que o construtor Create está definido como virtual, permitindo que classes que herdem dela possam sobrescrever o método. Porém, não existe nenhum tipo de implementação nela diferente e com isso, não há necessidade nenhuma de fazer isso. Visto que o construtor será o padrão (Aquele definido em TObject e que não executa nada de especial).

O destrutor Destroy só precisa ser implementado se vc possui alguma coisa a ser executada nesse momento, como um objeto interno da sua classe. Caso isso não aconteça, não é necessário implementar o destrutor Destroy.

Para a sua classe de exemplo, uma correta implementação dessa classe seria algo como abaixo:
Código:
unit Base;

interface

uses Classes;

type
  TBase = class(TPersistent)
  end;

implementation

{ TBase }

end.

Só há necessidade de sobrescrever algum método da superclasse se vc pretender realizar alguma codificação adicional nele. Fora isso, não é necessário.


Para a outra classe, que está herdando de TBase:

Os métodos construtor e destrutor Create e Destroy devem, sempre, estar definidos no mais alto nível de visibilidade "public". Eles até podem ficar em outro nível quando algumas situações exigem tal procedimento mas, no seu caso, isso não é necessário.

O construtor Create, agora, possui uma implementação diferenciada que é o ShowMessage e por isso, deve ser sobrescrito.
Atente para que a execução dessa mensagem só será feita quando a classe TContasReceber for instanciada e nunca em nenhuma outra situação.

Novamente, não há necessidade de implementar o destrutor Destroy pois nada está sendo executado nele que exija tal coisa.

Código:
uses Classes,...., Base;

type
{$METHODINFO ON}
  TContasReceber = class(TBase)
  public
    constructor Create; override;
end;

constructor TContasReceber.Create;
begin
  inherited Create;
  ShowMessage('Agora sim!');
end;

end;



Espero ter ajudado.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
RodrigoFarias
Experiente
Experiente


Registrado: Domingo, 27 de Julho de 2008
Mensagens: 443

MensagemEnviada: Sex Mai 18, 2012 5:23 pm    Assunto: Responder com Citação

@tiagoshimizu, como você está instanciando sua classe?
Coloca o código fazendo favor.

Realmente não entendi o que está acontecendo. Simplesmente quer fazer ações no construtor do sua classe herdada ?

Algo como:
Código:

TClassTest = class(TPersistent)
    constructor Create;
end;

constructor TClassTest.Create;
begin
  ShowMessage('Chegou');
end;


Funciona normal.

Att.
_________________

Novo Find Uses Para Delphi - https://github.com/rfrezino/RFindUnit
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
tiagoshimizu
Membro Junior
Membro Junior


Registrado: Segunda-Feira, 28 de Setembro de 2009
Mensagens: 329

MensagemEnviada: Qui Set 27, 2012 8:35 pm    Assunto: Responder com Citação

Pessoal, desculpe reviver o tópico hehe, mas é que agora estou precisando muito desse bendito create em TPersistent.... o exemplo contido no site do Andreano Lanusse Exemplifica bem o que preciso:
http://www.andreanolanusse.com/pt/disponibilizando-metodos-de-uma-classe-como-server-methods-sem-usar-tservermodule-em-datasnap/ Criar uma conexão do tipo DBXConnection ao criar a unit e destruí-la ao finalizar...
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
tiagoshimizu
Membro Junior
Membro Junior


Registrado: Segunda-Feira, 28 de Setembro de 2009
Mensagens: 329

MensagemEnviada: Qui Set 27, 2012 9:40 pm    Assunto: Responder com Citação

Pessoal, acho que solucionei meu problema com o seguinte código:
Código:
public
  procedure AfterConstruction; override;
end;

procedure TfrmListBase.AfterConstruction;
begin
  inherited;
  //your stuff, always initialized, no matter what kind of constructor!
end;

http://stackoverflow.com/questions/772336/using-inherited-in-the-create-constructor-of-an-tobject
Obrigado a todos pela ajuda.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB