Newsgroup: it.scienza.informatica
Titolo: Le meraviglie del C++

Salve a tutti,
ho una quantomeno curiosa questione da sottoporvi. Qualche tempo fa
stavo scrivendo una funzione C++ (in ambiente Microsoft DevStudio97,
con il compilatore Visual C++ 5.0) il cui compito è di creare l'albero
delle directory. Natura vuole che tale funzione sia molto elegante
se ricorsiva, e così io l'ho scritta. Eccone lo stralcio più
significativo:
void CBrowseDlg::GetTree(CTreeCtrl* pTree, HTREEITEM hParent,
        CStringList sList)
{
        if (sList.IsEmpty()) return;
        CString dir = sList.RemoveHead();
        HTREEITEM hThisDir = pTree->InsertItem(dir, hParent, TVI_SORT);
        ::SetCurrentDirectory(dir);
        // ...
        // qui ci sono una decina di linee in cui viene cominciata una
        // nuova ricorsione se la directory corrente contiene a sua
        // volta delle sub-directory (è la famosa mutua-ricorsione
        // che era tanto bella in ML). Comunque, non viene toccato
        // in nessun'altra maniera il parametro 'sList'.
        // ...
        ::SetCurrentDirectory("..");
        GetTree(pTree, hParent, sList);
}
La classe CStringList è un'implementazione C++ delle comunissime liste
di stringhe; la funzione CStringList::RemoveHead() non fa altro che
rimuovere la stringa in testa alla lista e restituirla come valore.
Il resto (la CTreeCtrl, la chiamata alla API SetCurrentDirectory(),
etc.) si può tranquillamente ignorare. Anche per chi non ha molta
familiarità con C/C++, credo che questo frammento di codice non
presenti difficoltà estreme di comprensione.
Ordunque, sono andato a compilarlo, e l'ultimissima linea di codice
(quella in cui viene richiamata ricorsivamente la funzione GetTree())
dà questo curiosissimo messaggio di errore:
C:\Programmi\DevStudio\...\BrowseDlg.cpp(68) :
error C2664: 'GetTree' : cannot convert parameter 3 from 'class
CStringList' to 'class CStringList'
Ora, o sono io che sono diventato completamente begalino (più di
quanto attualmente non sia), oppure lì c'è veramente scritto "cannot
convert [...] from 'class CStringList' to 'class CStringList'".
Che diavolo fa il compilatore, si diverte a prendermi in giro?
A meno che ci sia qualcosa che non riesco ad intellegere, a me la
situazione sembra analoga a qualcuno che ti dice "il gelato non lo
voglio alla fragola, lo voglio alla fragola".
Comunque, il bello è che la cosa sembra funzionare con l'unico altro
compilatore C++ che ho, il buon vecchio Borland Turbo C++ 2.0 per DOS.
Naturalmente, non ho potuto copiare la funzione così com'è in
ambiente DOS; lasciando solo i pezzi che mi interessavano ho cercato
di creare qualcosa di simile, che contenesse comunque la stessa chiamata
ricorsiva a una funzione con un parametro che era una classe simile
a CStringList. Tutto a posto, nessun errore.
La cosa che mi insospettisce è che sono riuscito a porre rimedio alla
questione modificando la funzione come segue:
void GetTree(CTreeCtrl* pTree, HTREEITEM hParent, CStringList& rList);
Il terzo ed ultimo parametro è diventato una reference a CStringList
piuttosto che una CStringList stessa. Così funziona, ed effettivamente
è anche migliore come soluzione (in senso di ottimizzazione della
memoria); però non vedo perché l'altra versione non dovrebbe funzionare.
Non si tratta di un errore di link, né peggio ancora di un errore
a run-time. Nessuna delle istruzioni viene mai eseguita: sembrerebbe
proprio un errore di sintassi puro e semplice.
Mah... aspetto fiducioso i vostri commenti.
damio :D
---------------------------------------------------------------------
This statement is true if it is at the beginning of a paragraph or
if it is preceded by a false statement; it is false if preceded by
itself. This statement is true if it is at the beginning of a
paragraph or if it is preceded by a false statement; it is false if
preceded by itself. This statement is true if it is at the beginning
of a paragraph or if it is preceded by a false statement; it is false
if preceded by itself.
---------------------------------------------------------------------
Sent via Deja.com 
http://www.deja.com/
Before you buy.

Forse (ma molto forse), non è definito un operatore di copia per la classe,
cosa che ti impedisce un passaggio di variabile per copia.
O meglio, è definito ma non implementato, cosa che ti impedisce anche di
usare l'operatore di default.
--
Alessandro Monti

posso solo dire che l'implementazione M$ del C++ IMHO e' una schifezza,
a partire dalle pretese assurde di vedere dichiarati come virtual i
distruttori ancestor, non volevo crederci fino a che non l'ho visto
scritto sul manuale..roba inaudita,  per finire alla STL MOLTO poco
standard. 
Usa il gcc per win32 se puoi...
saluti
guglielmo

 scritto sul manuale..roba inaudita,  per finire alla STL MOLTO poco
vuoi dire i distruttori delle classi base?
Lorenzo
--
+-----------------------------------------------------+
|  Lorenzo Bettini    ICQ# lbetto, 16080134           |
|  PhD student in Computer Science                    |
|  Florence - Italy                                   |
|  Home Page        : 
http://w3.newnet.it/bettini
     |
|           
http://infostud.dsi.unifi.it/~bettini
     |
|  Mail Home        : 
lorenzo...@penteres.it
     |
|  Mail University  : 
bet...@dsi.unifi.it
            |
|  
http://www.mokabyte.it
       Java on line journal  |
|  
http://rap.dsi.unifi.it/xklaim
    XKlaim language  |
+-----------------------------------------------------+

 vuoi dire i distruttori delle classi base?
si
guglielmo

 
Allora non ho capito cosa e' che non ti piace con la dichiarazione
virtual dei distruttori anchestor...
