Newsgroup: it.comp.lang.c++
Titolo: Non so perché, ma me l'aspettavo...

class A
{
public:
     void f() const { delete this; }
};
int main()
{
     A* a = new A;
     a->f();
}
Kiuhnm

 }
?!?!?!
Cosa ti aspettavi????

 Cosa ti aspettavi????
Mi aspettavo che non vi fosse una protezione contro la distruzione, e 
infatti non c'è. Strano che non ci abbia mai pensato prima.
Per es.
---
class A
{
public:
	void f() const { delete this; }
};
void destroy(const A* a)
{
	a->f();
}
int main()
{
	const A* a = new A;
	destroy(a);
}
---
si compila correttamente e 'destroy' può distruggere (non è una 
modifica?) un oggetto costante.
Non è chiarissimo come si possa risolvere, a livello di design del 
linguaggio, questo piccola incoerenza (incoerenza per me, feature per 
voi, non so...).
Nel nostro caso particolare, si può ovviare in questo modo:
---
class A
{
	~A() {}
public:
	friend int main();
};
void destroy(const A*)
{
//	delete a;
}
int main()
{
	const A* a = new A;
	destroy(a);
	delete a;
}
---
Kiuhnm

 modifica?) un oggetto costante.
No, non direi sia considerata una modifica. Vedi il codice sotto:
class A {
public:
   void f() {}
};
int main(int,char**) {
   const A*a=new A; //*a e' "const"
   //  a->f(); //Questo non e' lecito, perche' f() non e' "const"
   delete a; //questo si'
}
Parimenti il tuo "delete this;", sebbene probabilmente disastroso, e' 
sintatticamente lecito.
Altrimenti, una volta creato un oggetto "const", non potresti piu' 
distruggerlo???
Sbaglio? C'e' qualcosa che non ho colto?
  bye
	av.

 modifica?) un oggetto costante.
Se vogliamo metterla sul piano filosofico, no, la distruzione non è un 
modifica, a meno che tu non voglia considerare l'"esistenza" come una 
proprietà dell'oggetto. (Sant'Anselmo sarebbe d'accordo.)
Visto che il distruttore viene invocato automaticamente su oggetti con 
lifetime automatico o statico anche se dichiarati const, non vedo alcuna 
incoerenza nel fatto che 'delete' possa essere applicato a oggetti const.
Max

 incoerenza nel fatto che 'delete' possa essere applicato a oggetti const.
Aggiungo che nel draft dello standard c'era una nota (quindi a rigore 
non parte dello standard stesso):
[Note: a pointer to a const  type  can  be  the
   operand  of  a delete-expression; it is not necessary to cast away the
   constness (_expr.const.cast_) of the pointer expression before  it  is
   used as the operand of the delete-expression.  ]
  bye
	av.

 Sbaglio? C'e' qualcosa che non ho colto?
No, non sbagli. L'idea sarebbe di passare un oggetto assieme a dei 
permessi in modo da proibire certe operazioni. Forse si puň addirittura 
fare tramite i template. Ci penserň quando ho tempo.
Kiuhnm

 incoerenza nel fatto che 'delete' possa essere applicato a oggetti const.
Pur ammettendo che sia coerente, è pur sempre fonte d'errore.
Kiuhnm

 voi, non so...).
Il concetto e' che delete e' un'operazione sul puntatore e non sul
puntato. E' un po' analogo a come in UNIX per cancellare un file devi
avere il permesso di modifica sulla directory ma non necessariamente
sul file.
In piu', dal momento che i puntatori sono scalari, non e' possibile
"proteggere" un puntatore col const, dal momento che gli scalari
vengono manipolati per valore.
Il vero problema e' che quando e' stato inventato 'this' i reference
non esistevano ancora.
Comunque quello dell'oggetto che si cancella da solo per controllare il
proprio lifetime e' un idiom del C++ di qualche anno fa. Lo si ritrova
in ACE, per esempio.
D'altra parte anche questo e' immorale, ma non illegale:
#include <iostream>
#include <ostream>
class C {
  public:
    void f() { this->~C(); }
    ~C() { std::cout << "Autodistruzione!\n"; }
};
int main() {
  C c;
  c.f();
}
Ciao,
Nicola

 }
Questo non è legale; ha un comportemente indefinito. Si chiama
il destructor due volte.
--
James Kanze (GABI Software)             
email:james...@gmail.com
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, 
+33 (0)1 30 23 00 34