Newsgroup: it.comp.lang.c++
Titolo: delete classe

che problemi ci sono nel deallocare una classe con un metodo della stessa ?
esempio:
class cl{
public:
 int s;
 cl(){}
 void del(){delete this;}
 ~cl(){
  s=12;
  printf("delete \n");
 }
};
cl *tmp=new cl:
tmp.del();
(l'esempio non si riferisce al mio codice che è totalmente diverso )
capisco che non è un metodo intelligente ma dovro' usarlo..
grazie :))

 grazie :))
penso sarebbe meglio studiare una soluzione alternativa, questa sarebbe
*veramente* meglio lasciarla perdere perchč potrebbe produrre bug
veramente insidiosi. Se proprio devi fare in questo modo almeno rendi
private il costruttore e il distruttore e usa una factory per allocare
istanze dell'oggetto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 istanze dell'oggetto.
purtroppo sono finestre che creo come documenti e vorrei che si
deallocassero da sole alla chiusura e di conseguenza non posso fare
altrimenti per non complicare il codice....
non so come intendi usare una factory ma non credo possa andare bene
Esiste un metodo che permetta di creare le classi solo dinamicamente?
ciao :))

 Esiste un metodo che permetta di creare le classi solo dinamicamente?
esiste, vedi sotto per un esempio:
class SoloDinamicamente
{
public:
   SoloDinamicamente* create ();   // all'interno chiami il costruttore
   void dispose ();   // all'interno chiami il distruttore
protected: 
   // di queste definisci poi solo quelle che ti servono.
   SoloDinamicamente ();
   SoloDinamicamente (SoloDinamicamente const&);
   SoloDinamicamente& operator = (SoloDinamicamente const&);
   ~SoloDinamicamente ();
};
SoloDinamicamente* SoloDinamicamente::create ()
{
   return new SoloDinamicamente ();
}
void SoloDinamicamente::dispose ()
{
   delete this;



e poi il metodo per usarla è questo :
SoloDinamicamente *tmp ;
tmp=tmp->create();//almeno g++ non da errori
tmp->dispose();
?
(scusa le possibili inesattezze dovute alla mia incompetenza)
ciao grazie :)

 ?
no, perchè mi sono dimenticato di dirti che create deve essere static (mea
culpa). Il metodo corretto diventa:
SoloDinamicamente* tmp = SoloDinamicamente::create ();
tmp->dispose ();   // questa era giusta.
sorry. Correggi quindi in
static SoloDinamicamente* create ();
nella dichiarazione.


 nella dichiarazione.
vero però funziona ugualmente quello che ti ho scritto......
forse è solo un'illusione ?
ciao :))

 forse č solo un'illusione ?
sě! ;-)
scherzi a parte, non usare il codice che hai scritto perchč non č
corretto, a prescindere dal fatto che compili e a runtime ottieni
quello che (tu credi) dovresti ottenere.

 quello che (tu credi) dovresti ottenere.
continuo a credere che sia la stessa cosa :))
cmq non ho una preparazione sufficiente per discutere questa posizione
,perciò mi ritiro in buon ordine
ciao e grazie :))

 ,perciň mi ritiro in buon ordine
no, non e` la stessa cosa: nel tuo codice fai una chiamata ad un metodo 
su un puntatore non valido (infatti non e` inizializzato): questo 
secondo lo standard e` un undefined behaviour.
Prova ad esempio a rendere create() virtual: probabilmente crashera`.
ciao Anto
-- 
"Computer science is not about computers any more than astronomy
is about telescopes." -- EW Dijkstra

 Prova ad esempio a rendere create() virtual: probabilmente crashera`.
create() non può essere virtual perchè è static.
Intuisco il ragionamento di Gianni: giacchè create() è static non serve
dereferenziare il puntatore per invocare la funzione. Questo è il motivo
per cui il codice presumibilmente funzionerà con tutte le implementazioni.
Nondimeno, come ha detto Antonio, dubito che lo Standard lo ammetta.
Incidentalmente, ci potremmo chiedere se e quando abbia realmente senso
invocare un membro statico specificando un puntatore o un riferimento a
un'instanza anzichè usare lo scope della classe.
Ebbene, sì, c'è un caso in cui ha senso. Vediamo se qualcuno lo sa.
Max

 Prova ad esempio a rendere create() virtual: probabilmente crashera`.
io non uso(infatti devo inizializzarlo) un puntatore valido in quanto nel
metodo create non si fanno uso delle variabili.L'usare il metodo all'interno
di una classe senza inizializzarla potra esserre stilisticamente sbagliato
ma viene invocato cmq.Per quanto riguarda rendere il metodo virtuale la cosa
non mi interessa anche perchè devo solo invocare una "new" per creare la
classe.Ti ricordo che lo scopo di tutto questo era solo di permettere di
creare la classe *solo dinamicamente*.
Preciso che tutto questo che ho detto è solo una constatazione dei fatti
,sono un principiante e volevo capire il perchè non serviva usare un metodo
static.
ciao :)
ps per max: non uso un metodo static la discussione era appunto su questo

 >
ops gianni sono sempre io..
(ho cambiato computer)
ciao

 Max
In Delphi (sono ultra-OT!!!) i costruttori possono essere virtuali (e tutti
i metodi "static", che lě son "class procedure"), per il fatto che, se T č
un tipo, esiste il tipo "class of T". Forse ti riferisci a una situazione
simile?
Il seguente programma stampa a video "TB.Create"...
<DELPHI_CODE>
type
  TA = class
  public constructor Create; virtual; end;
  TB = class (TA)
  public constructor Create; override; end;
constructor TA.Create; begin Writeln('TA.Create'); end;
constructor TB.Create; begin Writeln('TB.Create'); end;
type
  CA = class of TA;
var
  X: TA;
  metaX: CA;
begin
  metaX := TB;
  X := metaX.Create;
  X.Free;
end.
</DELPHI_CODE>
Ciao ciao,
    Rony


 Ebbene, sì, c'è un caso in cui ha senso. Vediamo se qualcuno lo sa.
forse nei meccanismi di callback dove ci si aspetta un puntatore a
funzione e non un puntatore a funzione membro?


 Ebbene, sě, c'č un caso in cui ha senso. Vediamo se qualcuno lo sa.
l'unico caso che mi viene in mente e`, come dice Simone, l'uso della 
funzione come callback; purtroppo se non erro questo uso non e` 
portabile dato che le funzioni statiche hanno pur sempre C++-linkage, a 
differenza delle extern "C" che hanno C-linkage; penso che su tutti i 
compilatori l'unica differenza sia il name mangling e quindi le statiche 
sia possano usare intercambiabilmente con le extern "C", pero` non credo 
sia assicurato dallo standard.
Cmq, quale era la soluzione al problema?


 un metodo static.
forse non ci siamo capiti: per fare quello che vuoi tu e` *necessaria* 
una funzione statica e *non* puoi usare un metodo "normale".
Il fatto che funzioni in entrambi i casi e` solo una *casualita`*: 
cambiando compilatore (o forse anche solo cambiando le opzioni con le 
quali compili il programma) il tuo codice potrebbe improvissamente non 
funzionare piu`.
Detto questo se vuoi usare un metodo bound sei libero di farlo, ma poi 
non dire che non ti avevamo avvisato ;-)


 funzionare piu`.
ma non voglio dire che sia giusto ci mancherebbe...
cmq ...
1) il compilatore difficilmente si potrà accorgere se la classe sia gia
stata istanziata la cosa si farebbe piuttosto complessa.
2) il metodo non viene chiamato riferendosi al puntatore per questo verra'
eseguito cmq .
3) se non usi variabili della classe ,solo un new non si riferisce a nessuna
variabile interna alla stessa
cmq detto questo mi atterrò alle vostre regole che sicuramente sarà giusto
rispettare
ciao :)

 funzione come callback;
Non ho capito. Io mi riferivo al fatto di usare la notazione p->f anzichè
T::f.
Comunque, ciò a cui pensavo è che a volte può essere sensato (per
aumentare la genericità del codice) usare la prima notazione anche se
sappiamo che il metodo può essere static. Ad es:
   template< class T >
   void func( T* p )
   {
          p->f();
   }
In questo modo func() funzionerà anche con i T in cui f non è static.
Max

 In questo modo func() funzionerą anche con i T in cui f non č static.
ma allora si puo usare p->f() anche se "p" non č allocata ?
vero che stilisticamente č brutto perņ si puo usare:))
ciao

    }
Sono d'accordo, anche se per garantire la portabilita' sarebbe bene
controllare che p non sia nullo, perdendo un poco in genericita'.
Ciao,
Nicola
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 In questo modo func() funzionerà anche con i T in cui f non è static.
non mi convince piu` di tanto: mi fai un esempio di funzione che puo` 
essere static o non-static? Sinceramente non mi viene in mente nulla.
E` un po' come voler cercare due funzioni "int f(int)" e "int f()" che 
facciano esattamente la stessa cosa, indipendentemente dal parametro: se 
nella prima versione il parametro c'e` e` ovvio che servira` a qualcosa, 
no?


 
Beh, potresti immaginare di avere due classi che ti consentano di
allocare memoria: la prima usa una semplice chiamata a 'malloc',
l'altra ha qualche strategia più sofisticata che richiede di mantenere
uno stato. Entrambe hanno un metodo 'allocate', ma soltanto la prima
lo può dichiarare come static.
Max