Newsgroup: it.comp.lang.delphi
Titolo: Domanda idiota sulle classi

Ciao a tutti, una domanda credo banale.
Come faccio a sapere se una istanza di una classe esiste ovvero, 
ammettendo di avere una classe TDisney, e una sia istanza pippo, come 
faccio a sapere se pippo è stato istanziato ?
ZioGian

ZioGian ha scritto:

In generale, quando crei un'istanza di un oggetto ne assegni il 
riferimento ad una variabile in modo da poter accedere ai suoi membri.
Non è obbligatorio, ma è una buona abitudine impostare tale variabile a 
*nil* quando l'oggetto viene distrutto richiamando il metodo /Free/, 
magari in una "soluzione unica" usando /FreeAndNil/.
Seguendo questa convenzione, se la variabile (o le variabili) che 
dovrebbe contenere un riferimento all'oggetto equivale a *nil*, esso non 
è istanziato.
Se il panorama che ho preso in considerazione è diverso da quello che 
intendevi tu, magari rispondi ancora spiegando meglio la condizione in 
cui ti trovi. :-)
Ciao,
   Marco.
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)

Assigned l'hai gia visto?
AS

 ZioGian ha scritto...[cut]
Grazie Marco per la risposta. Esauriente e chiara come al solito. In 
effetti avevo gia capito che dopo l'esecuzione di /free/ posso prenere 
la mia istanza pippo e porre pippo := nil e successivamente verificare 
la condizione pippo <> nil.
Mi chiedevo solo se esiste un metodo "automatico", anche in relazione al 
fatto che la mia classe discende da Tthread e che ho impostato 
freeonterminate a true. Quindi, automanticamente, alla classe viene 
fatto il free alla fine del metodo execute MA non viene puntata a NIL.
Probabilmente posso, dal tread principale, intercettare l'evento 
OnTerminate del thread e nella gestione di quell'evento porre il mio 
pippo := nil;
ZioGian


Non c'e' modo di cambiare l'indirizzo di memoria di un oggetto dall'interno, 
ovvero tramite suoi metodi.
L'unica possibilita', quindi, e' settare il riferimento a nil esplicitamente 
oppure tramite una funzione esterna (grazie al meccanismo di passaggio dei 
parametri per indirizzo, ovvero grazie alla keyword "var"). 

cicap ha scritto:

Attualmente, ho collegato a OnTerminate del mio thread l'esecuzione ci 
una procedura che esegue:
...
if sender= miooggetto then miooggetto:=NIL;
...
L'oggetto è gia stato freeato..forse come suggeriva marco avrei potutto 
applicare un oggetto.freeandnil sullo stesso evento.
Pare che il tutto funzioni senza problemi, per ora.
ZioGian


Come ti ho detto precedentemente "oggetto.freeandnil" non puo' settare a nil 
l'oggetto.
FreeAndNil e' una procedura globale non un metodo di TObject. 

 AS
Andrea

 questo tipo [...]
Almeno per il test di una variabile che non sia un puntatore ad un 
metodo, verificare il valore restituito da /Assigned/ o testare che la 
variabile sia diversa da *nil* non è molto differente. ;-)


[...]Come faccio a sapere se una istanza di una classe esiste ovvero
Formalmente non puoi.
In Delphi esiste la funzione Assigned() ma non può assicurarti che
un'istanza esista realmente, ma solo assicurarti che la variabile del
tipo della classe non contenga nil.  Se la deallocazione di un oggetto
è nelle tue mani, assicurati di usare FreeAndNil() anziché invocare il
semplice metodo Free().  Questo è l'unico modo per far coincidere le
due condizioni: una variabile che vale nil <-> non è presente
l'oggetto relativo in memoria.

 variabile sia diversa da *nil* non è molto differente. ;-)
Eh lo so, ma un test esplicito a <> nil salta all'occhio, una
chiamata ad Assigned, no... ;-)
Ciao,
Andrea

 ha scritto nel messaggio 
news:A17zf.3224$6e2....@news.edisontel.com...


vera assurdita'[...]
Non è affatto un'assurdità e, anzi, è addirittura una necessità,
perché, oltre al fatto che settare a nil una variabile potrebbe non
essere richiesto nella maggior parte dei casi, non è affatto detto che
il codice che dealloca possa/debba allo stesso tempo modificare il
valore del puntatore.

 ha scritto nel messaggio
news:8gdts1lmvjag9togo...@4ax.com...


 spieghi. [...]
E se il tuo puntatore di riferimento si trova in una lista *TList*, ad 
esempio, cosa accadrebbe?


 ha scritto nel messaggio 
news:43cf7...@newsgate.x-privat.org...


 posto a Nil cosi' anche il puntatore dell'oggetto List1: TList
Io vedo molti problemi nel caso in cui io voglia rimuovere il 
riferimento dell'oggetto dalla lista in quanto non sono più in grado di 
identificarlo.


Ti faccio un esempio [...]
Vedi sopra.

posto a Nil [...]
Non servirebbe comunque a nulla (una TList, tanto per riprendere
l'esempio, ha una serie di Items, che sono "copia" dei puntatori) e
poi una funzione, ad esempio, potrebbe accettare un puntatore costante
(const P: Pointer) e liberarne la memoria associata, senza
necessariamente poter modificare il valore del puntatore.

[...]Io vedo molti problemi nel caso [...]
A prescindere da casi specifici, non è una soluzione valida:
type
  TSmartList = class(TList)
  public
    destructor Destroy; override;
  end;
{ TSmartList }
destructor TSmartList.Destroy;
var
  I: Integer;
begin
  for I := 0 to Count-1 do
  begin
    Dispose(Items[I]);
    Items[I] := nil;
  end;
  inherited;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  A: PInteger;
  B: PInteger;
  C: PInteger;
begin
  New(A); //
  New(B);
  New(C);
  ShowMessageFmt('Prima della Free: A=%p B=%p C=%p', [A,B,C]);
  with TList.Create do
  begin
    Add(A);
    Add(B);
    Add(C);
    Free;
  end;
  ShowMessageFmt('Dopo la Free: A=%p B=%p C=%p', [A,B,C]);
end;

 ha scritto nel messaggio 
news:43cfbb90$1...@newsgate.x-privat.org...


[...]Devi poi considerare che TList non e' un semplice array di puntatori[...]
In soldoni, è esattamente quello.  In ogni caso, mi pare si continui a
discutere, confondendo due aspetti assolutamente distinti: la gestione
del valore del puntatore e la gestione della memoria puntata dal
puntatore.  Non è affatto detto che vi siano le condizioni per porre
il valore di un puntatore a nil, pur potendo deallocare la memoria
puntata e non è affatto detto che questo sia richiesto sempre (anzi,
quasi mai se ne sente la necessità).

 ha scritto nel messaggio 
news:p8svs1l5ulbcmauh9...@4ax.com...


 quasi mai se ne sente la necessità).
Questa Andrea e' una tua opinione, probabilmente derivante dal tipo di 
programmazione che di norma svolgi.
Se si fanno programmi che contengono codice a "basso livello" con oggetti 
particolari  creati a runtime e "autodistruggenti" terminata la loro 
operazione,
ti garantisco che sapere se un oggetto e' allocato o no e' Utilissimo se non 
ESSENZIALE.
Giorgio 

non l'originale!!!
Non poni a nil un bel niente, perché il puntatore const non è
modificabile (è const, appunto).

[...]ti garantisco che sapere se un oggetto e' allocato o no [...]
E io ti garantisco che non č essenziale, anzi ritengo pure sbagliato
doverlo testare.  Tu fammi un esempio ed io ti dimostro che sei in
errore ;-)

 No Marco se osservi i metodi di TList vedi che se fai [...]
Purtroppo sono stato impegnato in un corso e non ho potuto rispondere 
tempestivamente (solo ora posso farlo). :-)
Direi che ha detto tutto Andrea. Io sintetizzo semplicemente il mio 
pensiero riguardo al caso in esame - anche se sono infiniti i casi, come 
giustamente precisato da Andrea - in cui questa funzionalità provochi 
effetti assolutamente indesiderati.
/Free/ è un metodo come un altro, posso richiamarlo attraverso qualsiasi 
riferimento ad un oggetto in mio possesso, memorizzato in una lista, in 
una variabile o in qualsiasi altro "contenitore".
Il fatto di porre a *nil* un riferimento è una funzionalità in più che 
causa problemi in quanto il valore, come detto da Andrea, potrebbe 
essere una costante, quindi non modificabile, oppure parte di una lista 
dalla quale vorrei poterlo rimuovere quando voglio, e comunque non 
permetto che Delphi lo imposti automaticamente a *nil* oppure che si 
discrimini questa operazione a seconda che il riferimento sia contenuto 
in una variabile comune o in una struttura più complessa come una lista 
e così via.
In tutti i casi in cui c'è una "malagestione" del fatto che si considera 
allocato un oggetto quando un riferimento ad esso è diverso da *nil*, è 
sufficiente spiegare e insegnare come vengono gestiti gli oggetti in 
Delphi per promuoverne un uso consapevole, eventualmente citando l'uso 
di /FreeAndNil/ per eseguire entrambe le operazioni contemporaneamente o 
incentivare l'adozione di un meccanismo sicuro di verifica da parte 
dello sviluppatore.
Qualsiasi automatismo che si debba poi adattare al caso in esame 
generando ambiguità o mutando il comportamento a seconda del 
"contenitore", tenendo conto che esistono anche riferimenti ad 
interfacce e altre strutture dati complesse a mio avviso genera solo e 
soltanto confusione.
In sostanza, la spiegazione da dare è semplice: basta semplicemente 
sottolineare che un oggetto può essere distrutto chiamando il metodo 
/Free/ attraverso un riferimento che, indipendentemente dal luogo in cui 
è contenuto, può essere all'occorrenza impostato a *nil* se lo si 
desidera, o rimosso da una lista di appartenenza, o "dimenticato" se è 
una variabile locale.
Non ci sono altre complicazioni né controindicazioni, basta 
semplicemente sapere questo. :-)
Vado a nanna che sono in piedi da quasi 24 ore... non garantisco 
completamente tutto ciò che ho scritto... zzzzzz... :-D
Ciao,
   Marco.


una variabile locale.
Bravo Marco, sintetizzi sempre in maniera esemplare.  Condivido.