Página 1 de 2
Classe não é destruida ?
Enviado: 20 Out 2021 11:20
por rossine
Bom dia,
Hoje me deparei com a dúvida abaixo.
Reparem que eu altero o valor da variável "cVarTeste" e chamo novamente a classe "TMYCLASS()", mas reparem que a variável "cTeste" não muda seu valor.
Porque ? O que está faltando ?
Código: Selecionar todos
#include "hbclass.ch"
PROCEDURE Main()
local oClass
cls
public cVarTeste
cVarTeste := "001"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [001] - OK"
? ""
? "Tipo de variavel de [oClass]=", valtype(oClass)
? ""
oClass := NIL
? "Tipo de variavel de [oClass]=", valtype(oClass)
? ""
cVarTeste := "002"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [002] - Errado"
? ""
oClass := NIL
cVarTeste := "003"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [003] - Errado"
? ""
oClass := NIL
return NIL
//---------------------------------------------------------//
CREATE CLASS TMYCLASS
VAR cTeste INIT cVarTeste
METHOD New() CONSTRUCTOR
METHOD End()
DESTRUCTOR Destroy()
END CLASS
//---------------------------------------------------------//
METHOD New() CLASS TMYCLASS
return SELF
//---------------------------------------------------------//
METHOD Destroy CLASS TMYCLASS
::End()
return NIL
//---------------------------------------------------------//
METHOD End() CLASS TMYCLASS
? "Classe Destruida..."
? ""
return NIL
//---------------------------------------------------------//
Obrigado,
Classe não é destruida ?
Enviado: 20 Out 2021 12:43
por alxsts
Olá!
Deve ser algum bug do próprio Harbour. Eu só uso variáveis PUBLIC e PRIVATE em último caso... algum motivo para não trocar por LOCAL?
Alterando o teu código e mantento a variável PUBLIC, funciona:
Código: Selecionar todos
#include "hbclass.ch"
PROCEDURE Main()
local oClass
setmode(25,80)
cls
public cVarTeste
cVarTeste := "001"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [001] - OK"
? ""
? "Tipo de variavel de [oClass]=", valtype(oClass)
? ""
oClass := NIL
? "Tipo de variavel de [oClass]=", valtype(oClass)
? ""
cVarTeste := "002"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [002] - Errado"
? ""
oClass := NIL
cVarTeste := "003"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [003] - Errado"
? ""
oClass := NIL
return NIL
//---------------------------------------------------------//
CREATE CLASS TMYCLASS
VAR cTeste // INIT cVarTeste
METHOD New() CONSTRUCTOR
METHOD End()
DESTRUCTOR Destroy()
END CLASS
//---------------------------------------------------------//
METHOD New() CLASS TMYCLASS
self:cTeste := m->cVarTeste
return SELF
//---------------------------------------------------------//
METHOD Destroy CLASS TMYCLASS
::End()
return NIL
//---------------------------------------------------------//
METHOD End() CLASS TMYCLASS
? "Classe Destruida..."
? ""
return NIL
//---------------------------------------------------------//
001 <- Aqui teria que ser [001] - OK Tipo de variavel de [oClass]= O Classe Destruida... Tipo de variavel de [oClass]= U 002 <- Aqui teria que ser [002] - Errado Classe Destruida... 003 <- Aqui teria que ser [003] - Errado Classe Destruida...
C:\hb32\Test\ClasseVarPublica>
Eu faria assim:
Código: Selecionar todos
#include "hbclass.ch"
PROCEDURE Main()
local oClass, cVarTeste
setmode(25,80)
cls
//public cVarTeste
cVarTeste := "001"
oClass := TMYCLASS():New( cVarTeste )
? oClass:cTeste, " <- Aqui teria que ser [001] - OK"
? ""
? "Tipo de variavel de [oClass]=", valtype(oClass)
? ""
oClass := NIL
? "Tipo de variavel de [oClass]=", valtype(oClass)
? ""
cVarTeste := "002"
oClass := TMYCLASS():New( cVarTeste )
? oClass:cTeste, " <- Aqui teria que ser [002] - Errado"
? ""
oClass := NIL
cVarTeste := "003"
oClass := TMYCLASS():New( cVarTeste )
? oClass:cTeste, " <- Aqui teria que ser [003] - Errado"
? ""
oClass := NIL
return NIL
//---------------------------------------------------------//
CREATE CLASS TMYCLASS
VAR cTeste // INIT cVarTeste
METHOD New() CONSTRUCTOR
METHOD End()
DESTRUCTOR Destroy()
END CLASS
//---------------------------------------------------------//
METHOD New( x ) CLASS TMYCLASS
self:cTeste := x
return SELF
//---------------------------------------------------------//
METHOD Destroy CLASS TMYCLASS
::End()
return NIL
//---------------------------------------------------------//
METHOD End() CLASS TMYCLASS
? "Classe Destruida..."
? ""
return NIL
//---------------------------------------------------------//
001 <- Aqui teria que ser [001] - OK Tipo de variavel de [oClass]= O Classe Destruida... Tipo de variavel de [oClass]= U 002 <- Aqui teria que ser [002] - Errado Classe Destruida... 003 <- Aqui teria que ser [003] - Errado Classe Destruida...
C:\hb32\Test\ClasseVarPublica>
Classe não é destruida ?
Enviado: 20 Out 2021 13:10
por rossine
Olá Alexandre,
A forma que você postou, passando a variável por "parâmetro", seria a forma correta mesmo e também faço assim, mas por acaso fiz uma classe definindo uma variável "data"recebendo o valor de uma variável do tipo "public" aí surgiu esta dúvida.
Obrigado pelo exemplo,
Classe não é destruida ?
Enviado: 20 Out 2021 13:12
por Fernando queiroz
Código: Selecionar todos
CREATE CLASS RECEBERCLASS
VAR oServer
METHOD New( ParamServer ) INLINE ::oServer := ParamServer, Self
METHOD RECEBER_MANUTENCAO( )
METHOD RECEBER_ATUALIZA_CREDITO_CLIENTE( CLIENTES_ID )
METHOD RECEBER_MOVIMENTO_BAIXA( )
PROTECTED:
VAR nFormato INIT 1
VAR cDefaultPrinter INIT WIN_PRINTERGETDEFAULT()
VAR cReportOption
VAR nPrinterType
VAR nCLIENTES_ID INIT 0
VAR dPERINI INIT M->DAT_HOJE-30
VAR dPERFIN INIT M->DAT_HOJE
VAR cFileName INIT "C:\TEMP\RECEBER_"+strzero(HB_RandomInt(1, 99999999),8,0)+'.PDF'
METHOD RECEBER_MANUTENCAO_onDlgInit( oDlg )
METHOD A_RECEBER_CARREGA( cConsulta )
METHOD A_RECEBER_onKeyDown( oBrowse1, nKeyPress, oDlg, cProgressKey, cAlvo_Consulta )
ENDCLASS
tenho usado assim, variáveis de acesso externo e variáveis usadas somente dentro da classe , classes totalmente independentes, quando preciso de algum parâmetro passo na chamada.
a classe inicia e termina nela mesmo
Classe não é destruida ?
Enviado: 20 Out 2021 13:32
por Fernando queiroz
tudo que acontece em LAS VEGAS fica em LAS VEGAS, tudo que acontece na class fica na class
entao crie metodos para sets e gets
tipo envie para a classe por parâmetro ou não a variável que você que e pegue o retorno dela alterado via gets
ex:
cVarTeste := "001"
oClass := TMYCLASS():New()
oClass:cVarTest := cVarTeste
e depois
cVarTeste := oClass:cVarTest
Classe não é destruida ?
Enviado: 20 Out 2021 13:32
por rossine
Olá Fernando,
Também faço assim, mas por acaso fiz uma nova classe desta maneira que citei uma "var" recebendo uma variável do tipo "publica", aí vi que aparentemente, mesmo "destruindo a classe" com "oClass := NIL", parece que a classe não é realmente destruída da memória, achei isso estranho e pode causar "leaks de memória".
Obrigado,
Classe não é destruida ?
Enviado: 20 Out 2021 16:14
por JoséQuintas
Tem que pensar o seguinte:
A classe é INICIADA, quando executa pela primeira vez, ou quando usa o NEW?
E quando destrói, é destruído somente o OBJETO ou toda informação da classe?
É.... parece a mesma coisa, mas não é.
E onde é executada a criação da classe propriamente dita?
É no momento do fonte, com acesso às variáveis do fonte, ou em um ponto isolado sem exergar variáveis ou só acessa as variáveis no primeiro uso? independente de New() ou não?
Uma coisa é:
o fonte da classe -> em algum momento vira realmente uma classe pra ser usada
o New() -> será que parte do zero, ou será que aproveita essa criação anterior?
o Destroy() -> destrói o que foi criado com new() ou tudo?
Digamos igual compilar um programa, onde pode ser gerada uma LIB, e depois usar a LIB.
De repente, existe uma "lib intermediária" criada pra uso de classe.
E por isso precisa do New()
Até já colocaram aí, ao invés de:
Altere pra:
Código: Selecionar todos
VAR cTeste
METHOD New() INLINE cTeste := cVarTeste, Self
Qual a diferença?
A variável vai ser verificada/alimentada no momento que usar classe():New()
Vai ter certeza de que o New() vai ser executado com a variável que quer.
Quanto a Destroy().... nunca usei.
Classe não é destruida ?
Enviado: 20 Out 2021 16:24
por JoséQuintas
Talvez seu problema tenha ajudado a resolver um problema aqui comigo.
Talvez eu tenha cometido um erro parecido com o seu, e por isso tenho alguns erros eventuais.
Vou mover pro New() e ver o que acontece.
Classe não é destruida ?
Enviado: 20 Out 2021 16:34
por JoséQuintas
Já comentei por aqui, problemas eventuais em browse.
De repente, aonde pensei estar criando uma nova cnSQL, estou usando sempre a mesma, e isso explicaria erros eventuais.
Conclusão:
INIT é pra coisas fixas, qualquer coisa diferente de constante deve ficar em new()
Essa foi a impressão que eu tive, depois de ver este tópico.
Classe não é destruida ?
Enviado: 20 Out 2021 16:43
por JoséQuintas
Na sefazclass tive um outro problema, e resolvi assim:
Código: Selecionar todos
METHOD Init() CLASS NfeTransporteClass
::Volumes := NfeVolumesClass():New()
RETURN SELF
Não podia usar isso no VAR Volumes INIT NfeVolumesClass():New()
Talvez seja a solução para esse caso também, ao invés de usar o New()
Classe não é destruida ?
Enviado: 20 Out 2021 16:48
por JoséQuintas
BINGO !!!!!
Código: Selecionar todos
REQUEST HB_CODEPAGE_PTISO
#include "hbclass.ch"
MEMVAR cVarTeste
PROCEDURE main()
LOCAL oClass
PUBLIC cVarTeste
Set( _SET_CODEPAGE, "PTISO" )
SetMode(40,100)
CLS
cVarTeste := "001"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [001] - OK"
? ""
? "Tipo de variavel de [oClass]=", valtype(oClass)
? ""
oClass := NIL
? "Tipo de variavel de [oClass]=", valtype(oClass)
? ""
cVarTeste := "002"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [002] - Errado"
? ""
oClass := NIL
cVarTeste := "003"
oClass := TMYCLASS():New()
? oClass:cTeste, " <- Aqui teria que ser [003] - Errado"
? ""
oClass := NIL
Inkey(0)
RETURN
CREATE CLASS TMYCLASS
VAR cTeste
METHOD INIT() INLINE ::cTeste := cVarTeste
ENDCLASS
Classe não é destruida ?
Enviado: 20 Out 2021 17:33
por rossine
Olá José,
Primeiramente obrigado por todas as postagens e explicações.
Não me lembrava que, quando a classe é iniciada "New()", é disparado automaticamente o método "Init()"
Então podemos definir estas variáveis "publicas/privadas" ou disparar funções que retornem valores, igual ao teu caso "ADOLocal()", dentro deste método "Init()"
Mas como então do lado do Harbour não é retornado nenhuma (Mensagem / Alerta / Erro) (Isto seria um possível BUG no Harbour ?), fica a dica sobre este assunto.
Só mais uma pergunta. Quando eu destruo o objeto , "oClass := NIL" automaticamente todos as "VAR / DATA" não teriam que automaticamente serem destruídas ?
Não sei se teria como saber o valor destas "VARS" ? ...porque o objeto principal já foi destruído.
Classe não é destruida ?
Enviado: 20 Out 2021 17:47
por JoséQuintas
rossine escreveu:Não sei se teria como saber o valor destas "VARS" ? ...porque o objeto principal já foi destruído.
Pois é... acho que não.
Quer um exemplo simples:
CLASSVAR é pra manter a variável em tudo que é instância criada.
Se o "modelo" fosse destruído, como é o que Harbour lembraria disso nas próximas vezes?
Acho que é como mencionei:
o Harbour cria um modelo de classe pra ser usado dali pra frente.
Mesmo que destrua o objeto, o tal modelo continua existindo.
Teoricamente, INIT é a parte fixa pré-definida da classe, fica pronta no modelo sempre.
Já o método INIT é executado a cada New(), a cada objeto "real".
Talvez tenha algo no changelog, porque lembro de uma época quando isolaram o New() do Init().
Lembro de falarem disso, mas na época eu nem mexia com classe, então não sei dizer do que se tratava.
Classe não é destruida ?
Enviado: 20 Out 2021 18:01
por JoséQuintas
JoséQuintas escreveu:CLASSVAR é pra manter a variável em tudo que é instância criada.
Se o "modelo" fosse destruído, como é o que Harbour lembraria disso nas próximas vezes?
E mais que isso:
Em HWGUI CLASSVAR é usado pra controlar FORMS e DIALOGS abertos.
Qualquer classe vai ter a lista de tudo que estiver aberto.
Saiba que em multithread TUDO é isolado, nem mesmo DBFs abertos ficam visíveis, cada thread pode ter sua própria área 1, 2, 3, cada thread usando arquivos diferentes.
E mesmo assim, isso de CLASSVAR passa por todo esse isolamento, o Harbour lembra dos detalhes da "classe modelo".
Então, sem dúvida, é como se as classes fossem compiladas em run-time, e a partir daí cada New() apenas cria o objeto partindo dessas classes "compiladas", e não se trata de simplesmente executar o fonte de criação da classe. Com isso o que está em VAR...INIT já foi feito antes, e não vai ser feito de novo.
Essa é a explicação que vejo fazer sentido, e os fontes do post parecem comprovar isso.
E talvez o modelo fique numa área isolada, aonde essas variáveis usadas não existem mais, apenas as constantes, e isso explicaria o Nil que retorna depois.
Classe não é destruida ?
Enviado: 20 Out 2021 18:55
por JoséQuintas
Tava testando aqui referente aquela variável cnSQL.
Por mais que eu entre e saia do aplicativo e/ou dos módulos, as mesmas conexões são mantidas.
Só encerra mesmo se fechar o aplicativo e aguardar alguns segundos.
Até as classes do Windows ficam lembrando das coisas kkkk