Newsgroup: it.comp.lang.c++
Titolo: std::deque e distruttori

 
Sbagli nell'aspettarti che un container standard di puntatori si occupi di
controllare il lifetime degli oggetti a cui i propri elementi puntano.
Max

 sbaglio, ma dove?
Tu utilizzi una deque di puntatori a A_core. Quando utilizzi la memoria dinamica ti riservi ogni diritto sul ciclo di
vita di un oggetto. Questo significa che hai la responsabilità di distruggerlo a mano. Se vuoi che venga autoeliminato
devi usare una deque di smart pointers (std::auto_ptr non va bene, ce ne vuole uno a semantica di possesso condiviso
prova a guardare Effective C++ di Scott Meyers oppure il mio articolo presente su 
programmazione.it
 nella sezione C++).
Altrimenti devi utilizzare il delete come stai facendo!
Ciao,
----------------------------------------------
Fulvio Esposito
WWW: 
http://digilander.iol.it/fesposito
E-Mail Contact me at: 
ful...@libero.it
----------------------------------------------

 condiviso 
solo una precisazione:
dici che per creare un container di smart pointers occorre che questi 
ultimi abbiano una semantica di shared ownership. In realta` non e` del 
tutto vero: per utilizzare container di smart pointers occorre che essi 
implementino una corretta semantica di copia (i.e. la copia deve essere 
uguale all'originale e l'originale non deve essere modificato): nello 
specifico l'ownership e` un aspetto ortogonale alla semantica di copia 
(anche se nel caso di std::auto_ptr sono indubbiamente legati l'uno 
all'altra).
Tanto per fare un esempio di smart pointer con ownership esclusiva ma 
corretta semantica di copia (molto scarno):
template<class T>
class Deep_copy_smart_ptr {
        T* ptr;
public:
        Deep_copy_smart_ptr(T* p): ptr(p) { }
        ~Deep_copy_smart_ptr() { delete ptr; }
        // copy ctor
        Deep_copy_smart_ptr( const Deep_copy_smart_ptr& p)
                : ptr( new T( *(p.ptr) ) ) { }
        // operator= simile al copy ctor
        // altri metodi, come operator->, ecc.
};      
std::vector< Deep_copy_smart_ptr<int> > v; // OK
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

uguale all'originale e l'originale non deve essere modificato)
Su questo concetto che personalmente ritengo molto fumoso di
"uguale all'originale" e che viene purtroppo usato anche dallo
standard c'e' stato un thread qualche tempo fa su comp.std.c++.
La mia opinione e' che sia meglio evitare termini del genere
(a cui risulta difficile assegnare un significato preciso),
e dire piuttosto che un container e' libero di fare un numero
arbitrario di operazioni di copia/assegnazione sugli elementi.
Andrea

 arbitrario di operazioni di copia/assegnazione sugli elementi.
beh, anche dicendo cosi` non copri tutta la casistica possibile: basta 
l'esempio di un container di auto_ptr<>: e` perfettamente lecito fare un 
numero arbitrario di copie, con il "difetto" che ognuna di queste copie 
modifica l'oggetto sorgente!
Penso che una definizione piu` precisa riguardo alla semantica di copia 
richiesta da un contenitore (che immagino corrisponda a quello che 
intendevi) possa essere questa:
1) durante l'operazione di copia l'oggetto sorgente deve rimanere 
invariato
2) e` perfettamente ammissibile che, dopo un certo numero di operazioni 
sul contenitore, gli oggetti contenuti non siano piu` quelli "originali" 
ma siano stati costruiti da quelli per mezzo di copy ctor e/o operator=.
Al momento non mi viene in mente alcuna definizione piu` precisa o 
adirittura formale, pero` mi pare che rispecchi abbastanza bene la 
realta`.


 modifica l'oggetto sorgente!
E' espressamente vietato definire un container di auto_ptr<>.
ISO/IEC 14882:1998 
20.4.5.3
: "auto_ptr does not meet the
CopyConstructible and Assignable requirements for Standard Library
container elements and thus instantiating a Standard Library container
with an auto_ptr results in undefined behavior."
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy          loreti at pd dot infn dot it

 E' espressamente vietato definire un container di auto_ptr<>.
si, lo sapevo: probabilmente mi sono spiegato male.


ma siano stati costruiti da quelli per mezzo di copy ctor e/o operator=.
Effettivamente in quanto avevo scritto io non avevo
sottolineato che non e' detto che le assegnazioni/copie
possono essere fatte solo fra istanze contenute... ma anche
da/verso istanze temporanee che poi vengono distrutte.
Andrea

with an auto_ptr results in undefined behavior."
CopyConstructible e Assignable sono proprio quelle definizioni
formali associate a concetti confusi a cui facevo riferimento.
Si parla di istanze "equivalenti" senza formalizzare il termine
e, secondo me, non esiste una ovvia e semplice definizione.
Personalmente io eliminerei quei termini (come ho gia' detto
nel thread su comp.std.c++) dichiarando semplicemente cosa le
implementazioni sono autorizzate a fare (copie/swap/assegnazioni)
Andrea

 "Invariato" non e' ben definito. 
hai ragione ed in effetti sono d'accordo con te quando dici che non e` 
facile trovarne una definizione corretta.
In ogni caso con il punto (1) volevo indicare che il copy ctor dovrebbe 
prendere riferimenti a const piuttosto che riferimenti a non-const (come 
nel caso di auto_ptr) [in ogni caso anche questa definizione e` 
palesemente incompleta]
Ma lo standard non dice nulla al riguardo?


 Ma lo standard non dice nulla al riguardo?
Probabilmente è un'interpretazione errata del termine oggetto da parte vostra. Per lo standard un oggetto è una "region
of storage" e non un oggetto nel senso OO. Applicare invariato ad una region of storage penso chiarisca il significato!
Ciao,
--


chiarisca il significato!
Dal draft in mio possesso "Assignable" e' definito
formalmente come
  Expression:      t = u
  Return type:     T&
  Post-condition:  t is equivalent to u
Secondo te quale sarebbe il significato ? Che le due
aree di memoria sono identiche ? Un po' restrittivo...
ad esempio std::vector o std::string (se non-COW) non
sono in questo caso "assignable".
Il significato di codice "equivalente" e' abbastanza
chiaro... ma per "oggetto equivalente" le cose si
complicano abbastanza. Anche tentare di usare "codice
equivalente" per definire "oggetto equivalente" e'
una strada secondo me senza uscita.
Io come ho detto eviterei queste pere mentali in toto
affermando ad esempio che std::vector e' libero di
usare operator= (e costruttore di copia e std::swap)
liberamente su istanze contenute o temporanei
presupponendo una semantica simile a quella dei tipi
nativi. Cosa questo significhi per classi definite dal
programmatore non e' un problema della libreria.
In questo modo comunque escludi che mettere auto_ptr
in un std::vector sia una cosa sensata, senza pero'
impapinarti in sabbie mobili filosofiche.
Andrea