Newsgroup: it.comp.lang.c++
Titolo: F.A.Q. UFFICIALI DI IT.COMP.LANG.C++

========================================================================
                  F.A.Q. UFFICIALI DI IT.COMP.LANG.C++
                      revisione 1.6  -  22/01/2005
           a cura di diversi partecipanti di it.comp.lang.c++
========================================================================
Indice delle domande:
-1) Perche` dovrei leggere questo documento ?
0) Vorrei imparare il C++, e` necessario conoscere prima qualche altro
   linguaggio oppure posso imparare direttamente questo?
1) Che differenza esiste tra C++, Visual C++, Borland C++ Builder...?
2) Che differenza c'e` tra C e C++?
3) Dove posso trovare un compilatore C++ freeware?
4) Quale editor posso utilizzare per scrivere i miei programmi?
5) Dove posso trovare della documentazione sul C++ e lo standard?
6) Quali libri mi consigliate per imparare il C++ o perfezionare le
   mie conoscenze?
7) Che cosa e` la memoria dinamica? Come si usa?
8) Come posso allocare dinamicamente una matrice a piu` dimensioni e
   utilizzare la notazione M[i][j]?
9) Che cosa e` un header? Come si creano e come si usano?
10) Se separo le definizioni di un template dalla sua dichiarazione
    ponendole in file separati (.h e .cpp) non riesco ad istanziarlo.
    Come posso risolvere il problema?
11) Come si passa un array ad una funzione in C++?
12) Come posso generare numeri casuali?
13) Come mai ottengo sempre la stessa sequenza di numeri casuali?
14) La sequenza generata da rand() non e` molto buona, dove posso
    trovare generatori di numeri casuali piu` validi?
15) Che differenza c'e` tra STL e la libreria standard del C++?
16) Lavorando con i numeri in virgola mobile, non riesco ad ottenere
    risultati precisi, perche`?
17) a - void main() funziona perché non dovrei usarlo?
    b - Posso omettere di scrivere uno statement return in main?
    c - Posso scrivere una main ricorsiva?
18) Posso ereditare pubblicamente da una classe che non ha distruttore
    virtuale?
19) a - Come si sviluppano programmi con interfaccia utente grafica?
    b - E programmi con interfaccia a caratteri, ma a schermo pieno
        invece che linea per linea?
========================================================================
-1) Perche` dovrei leggere questo documento ?
R)  Potresti trovare qui le risposte alle tue domande rapidamente senza
    dover aspettare che qualcuno ti scriva. Magari se trovi risposte che
    ti fanno sorgere altre domande, cercale sempre in questo documento.
    Quando poi veramente non riesci a venirne fuori, cerca nel gruppo
    it.comp.lang.c++ con parole chiave del tuo problema su google:
 
http://groups.google.it/groups?hl=it&lr=&group=it.comp.lang.c%2B%2B
    (copia anche %2B%2B o la tua ricerca andra` su it.comp.lang.c)
    Magari esistono gia` risposte date da altri.
    Se non riesci a capire le risposte degli altri, controlla i termini
    usati su un tuo libro o in qualche sito web citato in questa faq.
    Questo potrebbe aiutarti anche nel porre poi la domanda ai
    partecipanti del gruppo.
    Se non hai tempo di fare tutto questo, ti verra` forse chiesto
    comunque di farlo, in modi piu' o meno cortesi. Se non hai tempo,
    evita quindi perdite di tempo e cerca di essere preciso nel
    formulare le domande.
 
    Ricordati anche di leggere il manifesto del gruppo:
 
http://www.news.nic.it/manif/it.comp.lang.c%2B%2B.html
0) Vorrei imparare il C++, e` necessario conoscere prima qualche altro
   linguaggio oppure posso imparare direttamente questo?
R) Il C++ e` un linguaggio estremamente ricco e complesso, e come
   tale puo` non essere il piu` adatto da imparare come primissimo
   linguaggio di programmazione; esso e` stato progettato (come il
   suo precursore "C") per l'uso da parte di programmatori esperti e
   "scafati". Molti altri linguaggi sono stati progettati
   specificamente per insegnare ai principianti a programmare: alcuni,
   come il Pascal, guidano molto il principiante obbligandolo ad
   imparare ed applicare una rigorosa disciplina; altri, come Rexx,
   Python, e Basic, sono invece (in diversa misura e con diverse
   filosofie) "tolleranti" e "di manica larga". L'uno, l'altro, o
   entrambi questi approcci potrebbero essere piu` produttivi per
   imparare a programmare che non tuffarsi alla "nuotare o affogare"
   nel pelago del C++.
   Per chi gia` sa programmare (in qualsiasi altro linguaggio, Pascal,
   Basic o altro) il C++ e` un ottimo "secondo passo" nel mondo della
   programmazione.  In particolare non e` certo il caso di vedere come
   propedeutici al C++ altri linguaggi simili ma diversi (come Java,
   Objective C, Eiffel, Smalltalk...), se l'obbiettivo e` il C++,
   meglio allora studiare il C++.
   C'e` un diffuso e stranissimo mito che il linguaggio C sia
   propedeutico al C++, poiche` storicamente ne fu la radice. Questo
   equivale a dire che, per chi voglia imparare l'Inglese, sarebbe
   furbo cominciare con il Sassone basso-medievale [1].
   In pratica i modi di programmare in C e in C++ sono talmente
   diversi che e` meglio passare direttamente al C++ e non acquisire
   idiomi tipici del C e del tutto superati e/o controproducenti nel
   C++.
   [1] Consulenza sul Sassone basso-medievale di Alex Martelli! :-)
1) Che differenza esiste tra C++, Visual C++, Borland C++ Builder...?
R) Il C++ e` il linguaggio definito dallo standard ANSI/ISO.
   Lo standard ne definisce la sintassi e la semantica dei costrutti,
   le regole che lo governano e la libreria standard. Di questo
   linguaggio esistono poi diverse implementazioni per le varie
   piattaforme (DOS, Linux, Windows, Mac...), alcune sono freeware
   (GNU gcc, Cygwin...) altre commerciali (Visual C++, Borland C++
   Builder). Queste implementazioni sono tutte piu` o meno aderenti
   allo standard, alcune offrono oltre al compilatore anche strumenti
   quali debugger e profiler, e/o delle estensioni non standard o
   particolare supporto ad una certa piattaforma. Ad esempio il
   Borland C++ Builder e` anche uno strumento R.A.D.
2) Che differenza c'e` tra C e C++?
R) Spesso si dice che il C++ e` una estensione del C, ovvero un
   "C + AltraRoba". Questa affermazione e` corretta ed errata allo
   stesso tempo. La correttezza sta nel fatto che effettivamente il
   C++ da un punto di vista sintattico e` un sovrainsieme del C,
   tuttavia queste sue estensioni modificano totalmente il modo in cui
   si programma in C++, al punto che l'approccio C e` totalmente
   diverso e superato.
3) Dove posso trovare un compilatore C++ freeware?
R) In rete e` possibile reperire diversi prodotti gratuiti, molti sono
   basati sul compilatore GNU gcc. Ecco un breve elenco di
   possibilita`:
   GNU gcc - 
http://gcc.gnu.org
   L'ottimo compilatore GNU, uno dei piu` aderenti allo standard,
   fornito di serie sui sistemi Linux e di cui esistono porting molto
   validi per DOS e Windows. E` possibile trovare anche molti tool a
   supporto di questo compilatori, in particolare l'ottimo debugger
   GNU gdb ed il profiler GNU gprof.
   DJGPP - 
http://www.delorie.com/djgpp
   E' il porting per MS-DOS del compilatore GNU gcc e viene aggiornato
   abbastanza frequentemente (almeno finora, ma la cosa potrebbe
   cambiare in futuro dato che l'MS-DOS tende sempre piu'
   all'obsolescenza).
   E' ottimo per imparare il C/C++ in quanto non mette troppa carne al
   fuoco (tipo programmazione Windows con finestre e bottoncini) ma
   offre compilatore e librerie con una buona aderenza allo standard.
   In piu' fornisce anche una nutrita serie di funzioni non standard,
   praticamente le stesse fornite con i compilatori Borland sempre
   per MS-DOS.
   Cygwin - 
http://www.cygwin.com
   Basato su un porting dell'ottimo GNU gcc, fornisce un ambiente unix
   like su piattaforma windows. Sono compresi diversi tool utili, in
   particolare anche gdb il debugger GNU, ma manca di un editor di
   risorse.
   Mingw - 
http://www.mingw.org/
   Sempre gcc per windows, anch'esso dotato tra l'altro di un
   debugger (GNU gdb) ed un profiler (GNU gprof). A differenza del
   precedente non offre un ambiente unix like.
   Ora ci sono anche quelli Microsoft e Intel, ottenibili e usabili
   entro certi limiti:
 
http://msdn.microsoft.com/visualc/vctoolkit2003/
 
http://www.intel.com/software/products/noncom/
4) Quale editor posso utilizzare per scrivere i miei programmi?
R) Qualunque editor ASCII va bene, anche il semplice Edit del DOS o
   il Vi di Linux, tuttavia e` possibile trovare editor specializzati
   con syntax hilight (che usano cioe` colori diversi per i vari
   elementi del linguaggio). Eccone una nutrita lista:
   QEdit
   E' un vecchio editor per MS-DOS molto snello ma potente e
   totalmente configurabile. Contiene anche un ricco macro-linguaggio.
   Ora e' sostituito dal successivo.
   The SemWare Editor - 
http://www.semware.com
   E' il successore di QEdit con molte caratteristiche in piu', una
   delle quali e' di utilizzare la memoria estesa per permettere
   l'editing di files molto grossi. Esiste anche in versione Windows
   ma sempre con interfaccia a caratteri.
   WinEdit - 
http://www.winedit.com
   E' un editor per Win32 che offre buona configurabilita' ed ottime
   caratteristiche tra le quali il WIL (Windows Interactive Language),
   un linguaggio molto ricco e potente che permette di creare
   praticamente qualsiasi comando di cui si puo' aver bisogno allo
   interno dell'editor stesso.
   UltraEdit - 
http://www.ultraedit.com
   E' un altro editor per Win32 molto simile al precedente che manca
   pero' del linguaggio WIL, ma offre in piu' la possibilita' di
   editing esadecimale.
   MultiEdit - 
http://www.multiedit.com
   Un altro editor ancora per Win32 (ma esiste anche la versione per
   Win16). Rispetto ai precedenti offre in piu' la possibilita' di
   configurare perfino i bitmap della toolbar per quanto riguarda i
   pulsanti definiti dall'utente. Per il resto sembra comunque
   inferiore ai due precedenti in quanto non offre editing
   esadecimale, il linguaggio macro sembra meno potente del WIL e, a
   differenza degli altri due, non presenta la classica struttura con
   tree delle cartelle sulla sinistra e finestra di editing sulla
   destra.
   EditPlus - 
http://www.editplus.com
   E` un ottimo editor di testo, con sistemi di high-lighting
   personalizzabili e, sul sito, ci sono i plug-in per gestire quasi
   tutti i linguaggi (alcuni sono presenti con l'installazione di
   base).
   Solo per piattaforma Win32.
   Texturizer - 
http://www.texturizer.net/
   Altro ottimo editor di testo per Windows, con sistemi di code
   highlighting, anch'essi personalizzabili, per moltissimi linguaggi.
   La cosa piu` interessante e` che ha un costo molto basso al
   confronto con altri strumenti simili per Windows.
   PFE - 
http://www.lancs.ac.uk/people/cpaap/pfe/
   Freeware per win32, con una serie notevole di personalizzazioni
   possibili (macro, file salvati in formato *unix*, cattura
   dell'output dei comandi batch, e cosi' via). Esiste anche una
   vecchia versione a 16 bit. Manca solo la sintassi colorata per
   raggiungere la perfezione.
   KDevelop - 
http://www.kdevelop.org
   Non e` un semplice editor, ma un IDE (un ambiente di sviluppo
   integrato) freeware per Linux con class tree, gestione di progetti,
   tool di sviluppo RAD per KDE, integrazione con debugger, browser
   integrato per la documentazione.
   CForge - 
http://www.codeforge.com
   Altro IDE per Linux ed altri SO molto completo. E` disponibile in
   una versione free (no opensource) per uso personale e piccoli
   progetti e varie versioni commerciali a prezzi contenuti.
   VIM - 
http://www.vim.org
   Estensione dello storico 'vi' per Unix disponibile anche per Windows.
   Dotato anche di interfaccia grafica con menu` per principianti.
   Diventa uno strumento velocissimo dopo un opportuno addestramento
   all'uso solo-tastiera. Impareggiabile dopo l'accostamento a GNU
   Screen. Consiglio di comprare il libro con il quale l'autore
   finanzia un progetto a scopo umanitario, oppure di scaricarlo,
   stamparlo e leggerselo lontano dal computer.
   Infine e` utile ricordare Emacs uno dei piu` potenti editor, dotato
   di mille funzionalita` e disponibile per molte piattaforme (Unix,
   Linux, Windows...). Lo si trova facilmente con una piccola ricerca
   in rete.
5) Dove posso trovare della documentazione sul C++ e lo standard?
R) Per lo standard ci sono 2 possibilita`, puoi comprarne una copia
   sotto forma di file pdf (Acrobat reader) all'indirizzo
 
http://webstore.ansi.org/ansidocstore/product.asp?sku=INCITS%2FISO%2FIEC+14882%2D2003
   per soli 18 US$, oppure puoi comprare la versione cartacea
   (molto piu` costosa) all'indirizzo 
http://webstore.ansi.org
   Per altra documentazione sul C++ eccoti nutrito elenco di indirizzi
   utili, la maggior parte dei quali riferisce per ovvie ragioni a
   risorse in lingua inglese:
 
http://www.icce.rug.nl/documents/cplusplus
   Faq del NG comp.lang.c++. In inglese
 
http://www.eskimo.com/~scs/C-faq/top.html
   Faq del NG comp.lang.c. In inglese.
   In queste FAQ sono spiegati in dettaglio i sequence points, non
   discussi sulle FAQ di comp.lang.c++
 
http://www.programmazione.it
   E` un sito dedicato alla programmazione in generale, ma contiene
   molto materiale relativo al C++ compreso un tutorial in italiano
   che pero` richiede delle conoscenze di base in materia di
   programmazione.
 
http://www.bruceeckel.com
   A partire da questo indirizzo e` possibile scaricare liberamente la
   nuova edizione di "Thinking in C++", l'ottimo libro di Bruce Eckel.
   Una traduzione in italiano del primo volume si trova su
 
http://pensareincpp.altervista.org
   In inglese, molto valido.
 
http://www.programmingtutorials.com/
 
http://www.cprogramming.com/
 
http://www.cyberdiem.com/vin/learn.html
   Su questi siti e` possibile trovare diversi tutorials ed altro
   sul C++ (ed anche sul C).
 
http://www.accu.org/
   Association of C and C++ users
 
http://www.utu.fi/~sisasa/oasis/oasis-cc++.html
 
http://www.la-online.com/cprog.htm
   link per C e C++ anche a documentazione varia
   Ecco dei link in cui si trova documentazione sulla
   libreria standard del C++ e su STL (vedere faq N. 15):
 
http://www.sgi.com/Technology/STL
 
http://www.dinkumware.com/refxcpp.html
 
http://www.cppreference.com/cpp_stl.html
   Alcuni Link sull'Object Oriented in generale:
 
http://www.cetus-links.org/
6) Quali libri mi consigliate per imparare il C++ o perfezionare le
   mie conoscenze?
R) Tra le risposte alla precedente domanda trovi un link da cui
   scaricare l'ottimo libro di Bruce Eckel, adatto sia per i
   principianti che per quelli che gia` conoscono molti aspetti del
   C++.
   Al momento attuale (gennaio 2000) questo libro e` in fase di
   pubblicazione. Altri testi sono elencati di seguito, di alcuni di
   essi potrebbe essere disponibile la traduzione in italiano che
   pero` potrebbe non essere all'altezza dell'originale.
   Lippman e Lajoie, "C++ Primer" 3 ed. - Addison Wesley
   Ottimo libro per chi vuole imparare il C++. Esiste anche la
   traduzione in italiano, intitolata "C++ Corso di Programmazione".
   B. Stroustrup, "The C++ programming language" 3 ed. - Addison
   Wesley
   E` il libro del padre del C++, non e` molto valido per chi deve
   iniziare, ma e` sicuramente un buon reference ed un approfondimento
   per un programmatore C++ con una certa conoscenza del linguaggio.
   B. Stroustrup, "The design and evolution of C++" - Addison Wesley
   E` rivolto a chi vuole approfondire le conoscenze sul perche` delle
   scelte operate nella realizzazione del C++ e sul funzionamento di
   certi meccanismi. Non e` molto aggiornato rispetto allo standard,
   ma e` tuttora molto valido. Rivolto a conoscitori abbastanza
   esperti del linguaggio.
   S. Meyers, "Effective C++" 2 edizione e "More Effective C++"
   editi da Addison wesley
   Due libri disponibili anche in formato elettronico (CD) ad un
   prezzo conveniente (piu` aggiornati rispetto alle edizioni cartacee
   e con un plus di articoli dell'autore).
   Si tratta di una raccolta di consigli su cosa fare (e come) e cosa
   non fare in C++. Caldamente consigliati a chi vuole fare del C++ un
   utilizzo professionale.
   C. Pescio, "C++ manuale di stile" - Edizioni Infomedia
   L'argomento trattato e` l'importanza dell'uso di uno stile nella
   codifica in C++ e i problemi che possono sorgere quando non si
   usano dei principi precisi e razionali.
   Di facile lettura, molto valido e ad un prezzo abbordabile.
   Renato Conte (
co...@dsi.unive.it
)
   "Il Mondo degli Oggetti: Programmazione in C++"
   Edizioni Progetto - Padova
   Buon libro, adatto a chi ha conoscenza di programmazione in Basic,
   Pascal o altro e vorrebbe imparare da 0 il C++, semplice, con tanti
   esempi, chiaro e bene impaginato. Essendo lo scrittore italiano ed
   essendo disponibile l'indirizzo e-mail e' possibile contattarlo per
   chiarimenti, suggerimenti o altro.
   Nicolai Josuttis,
   "The C++ standard library, a tutorial and a reference"
   Addison-Wesley
   Un altro ottimo testo.
   J.Coplien,
   "Advanced C++ Programming Styles and Idioms"
   Addison Wesley?
   Il breve commento che lo descrive sul sito di Infomedia:
   "Per approfondire le caratteristiche del linguaggio. Tra cui:
   programmazione object oriented, ereditarieta' multipla, tipi di
   dati astratti ed altro".
   In realta' sono trattati argomenti anche un po' distanti dal C++
   (o meglio concetti che derivano da altri linguaggi, come per
   esempio la Programmazione Orientata agli Accessi, tecniche di
   Reflection, ecc.).
   Purtroppo e` molto datato ma puo` essere comunque una lettura
   assai interessante.
   J.Coplien,
   "Multi-Paradigm DESIGN for C++"
   E` piu` un libro sul design del software che sulla programmazione,
   d'altronde pero` il design e` importante almeno tanto quanto
   la programmazione.
   E. Gamma, R. Helm, R. Johnson, J. Vlissides
   "Design Patterns, Elements of reusable Object-Oriented Software"
   Addison Wesley
   Una raccolta di pattern molto importanti e di impiego generale, non
   tratta dunque la programmazione in C++, ma ha piu` a che vedere col
   design. Non deve mancare nella libreria (e nella testa) di un
   professionista del C++.
   J. Lakos
   "Large-Scale C++ Software Design"
   Addison Wesley
   Dedicato alla progettazione di applicazioni C++ (molto) grosse!
   E` possibile trovare delle recensioni su questi ed altri libri
   sul sito 
http://www.accu.org/bookreviews/public/index.htm
7) Che cosa e` la memoria dinamica? Come si usa?
R) In C++ e` possibile allocare la memoria solo quando serve, ad
   esempio quando non si sa a priori quanta memoria serve per
   memorizzare una lista di valori di un certo tipo.
   Questa memoria la si alloca e dealloca attraverso l'uso dei
   puntatori e degli operatori new (new[]) e delete (delete[]).
   Ad esempio se vogliamo allocare memoria per una variabile di tipo
   T possiamo scrivere:
   T* VarPtr = new T(/* parametri costruttore */);
   Per utilizzare questa variabile basta dereferenziare VarPtr:
   std::cout << *VarPtr << std::endl; // supponendo l'esistenza di
                              // ostream& operator<<(ostream&, T&)
   *VarPtr = NewValue         // assegnamento...
   Per allocare un intero array bisogna utilizzare invece la forma
   T* MyArray = new T[Size];
   std::cout << MyArray[0] << std::endl;
   MyArray[5] = NewValue;
   E` necessario ricordarsi di deallocare la memoria dinamica
   quando non serve utilizzando sempre e solo l'apposito operatore:
   delete VarPtr;     // per singoli elementi
   delete[] MyArray;  // per gli array
   In C sono poi disponibili anche le funzioni malloc e free, ma il
   loro uso e` sconsigliato in C++.
   Infine e` spesso assai piu` proficuo utilizzare le classi
   fornite dalla libreria standard del C++ che sollevano il
   programmatore dalla necessita` di tenere traccia delle
   allocazioni e delle deallocazioni semplificandone il lavoro.
   Ad esempio std::auto_ptr<> e` una classe che incapsula un
   puntatore intelligente che quando distrutto libera automaticamente
   anche la memoria.
   Un altro approccio si basa sull'uso di classi come std::vector<>
   std::vector<T> vT;
   // un T alla volta...:
   vT.push_back(T());    // con il ctor di default
   // e/o, anche, molti T alla volta...:
   vT.resize(23);           // altri 22 ctor di default
   vT.push_back(T(args));    // con altri ctor
   Questo ha tra l'altro gli stessi vantaggi di std::auto_ptr<>,
   in quanto gli oggetti contenuti in vT vengono automaticamente
   cancellati dal distruttore di vT stesso.
   Esistono anche altri contenitori standard, come std::list<>,
   std::set<>, std::map<>, ..., per esigenze particolari, ma
   std::vector<> e` di gran lunga il piu` utile e comune per
   la semplice allocazione dinamica.  Per il caso particolare,
   molto comune, di stringhe di caratteri di lunghezza dinamicamente
   variabile, std::string (e std::wstring, per usare Unicode) sono
   anche molto, molto pratiche.
   Il C++, essendo un linguaggio adatto anche a "programmazione di
   sistema" (cioe` di bassissimo livello), offre anche delle forme
   alternative di allocazione dinamica, che sono quelle che,
   internamente, strutture come std::vector possono usare per offrire
   la loro comoda ed efficiente funzionalita` (queste funzionalita`
   vanno incapsulate in un oggetto di tipo "allocatore" perche`
   std::vector e soci possano poi usarle).
   In pratica, non si presenta mai una vera necessita` di
   accedere a queste funzionalita` di bassissimo livello
   (come new[]/delete[], malloc/free, e altre, meno portatili, come
   sbrk su Unix, VirtualAllocEx su Win32, CoTaskMemAlloc nell'ambito
   di un utilizzo del COM o DCOM, eccetera eccetera), se non per
   compatibilita` con vecchio codice scritto con l'uso di esse, o
   interfacce di sistema di bassissimo livello; infatti, std::vector
   (e gli altri contenitori standard) fanno in pratica tutto quello
   che serve, al limite con l'aiuto di un oggetto allocatore non
   standard per esigenze peculiari.
8) Come posso allocare dinamicamente una matrice a piu` dimensioni e
   utilizzare la notazione M[i][j]?
R) Ecco alcune possibilita`, alcune richiedono un po' di impegno,
   studiatele bene prima di porre eventuali quesiti sul NG.
   Approccio tradizionale di basso livello:
   #include <iostream>
   #include <iomanip>
   using namespace std;
   int main() {
     int** Matrice = new int* [10];
     // alloca la prima dimensione
     for(int i=0; i<10; ++i)
       Matrice[i] = new int [10];
     // allocazione della seconda dimensione
     // e inizializzazione della matrice
     for(int i=0; i<10; ++i)
       for(int j=0; j<10; ++j)
         Matrice[i][j] = (i+1) * (j+1);
     // visualizza il valore dei vari elementi
     for(int i=0; i<10; ++i) {
       for(int j=0; j<10; ++j)
         std::cout << setw(3) << Matrice[i][j] << " ";
        std::cout << std::endl;
      }
     // Deallocazione della matrice.
     // Notare che la deallocazione avviene in ordine
     // inverso rispetto all'allocazione
     for(int i=0; i<10; ++i)
        delete[] Matrice[i];
     delete[] Matrice;
   }
   Un approccio basato su vector:
   #include <vector>
   template<class T>
   class matrix {
       typedef std::vector<T> riga;
       std::vector<riga> body;
     public:
       void setSize(int x, int y) {
         body.resize(0);    // getta tutto
         body.resize(x);    // riparte
         for(int i=0; i<x; ++i)
           body[i].resize(y);
       }
       void getSize(int &x, int &y) {
         x = body.size();
         if(x) y=body[0].size();
         else y=0;
       }
       matrix() {}
       matrix(int x, int y) { setSize(x,y); }
       // non occorre dtor esplicito, quello di
       // default e` OK
       std::vector<T>& operator[](int i) { return body[i]; }
       const std::vector<T>& operator[](int i) const { return body[i]; }
   };
   Un altro, piu` a basso livello e che presenta eguale
   interfaccia d'uso pur utilizzando in realta` un semplice
   vettore e non una matrice:
   template<class T>
   class matrix {
       T* body;
       int x; int y;
     public:
       void setSize(int x, int y) {
         if(body) delete[] body;    // getta tutto
         body = new T[x*y];         // riparte
         this->x = x;
         this->y = y;
       }
       void getSize(int &x, int &y) {
         x = this->x;
         y = this->y;
       }
       matrix(): body(0) {}
       matrix(int x, int y): body(0) { setSize(x,y); }
       ~matrix() { if(body) delete[] body; }
       T* operator[](int i) { return body+i*y; }
       const T* operator[](int i) const { return body+i*y; }
   };
9) Che cosa e` un header? Come si creano e come si usano?
R) Un header e' un file di testo (con estensione .h o .hpp o altro)
   contenente normalmente dichiarazioni di funzioni, tipi, classi...
   Lo scopo principale di un header file e' quello di raggruppare in
   un unico punto del programma tutte le dichiarazioni relative ad un
   certo argomento (ad esempio, parlando di header files standard,
   tutte quelle riguardanti l'I/O su stream o quelle riguardanti il
   tipo std::vector) ed evitare cosi' possibili errori di battitura da
   parte del programmatore e rendere piu` gestibile un programma.
   In un file header e` comunque possibile (e in alcuni casi
   necessario) inserire anche definizioni di funzioni, variabili,
   costanti...
   Una volta creato un header per utilizzarlo si utilizza la direttiva
   #include "file.h" all'interno dei file che ne fanno uso.
   Notare che che gli header standard non ereditati dal C sono privi
   di estensione '.h'.
   Per maggiori dettagli si rimanda ad un qualsiasi libro (tutorial)
   su C/C++.
10) Se separo le definizioni di un template dalla sua dichiarazione
    ponendole in file separati (.h e .cpp) non riesco ad istanziarlo.
    Come posso risolvere il problema?
R)  Gli attuali compilatori hanno bisogno di avere completo accesso
    sia alla dichiarazione che alla definizione di un template quando
    questo viene istanziato. Come conseguenza di cio` non e`
    possibile separare le definizioni dalle dichiarazioni, tutto deve
    essere messo in un unico file header (.h).
    Un modo per risolvere il problema è dire al compilatore per quali
    tipi la 'template class' sarà instanziata.
    Ad esempio:
    // file handle.h
    template<typename T>
    class handle
    {
    public:
        void fun( const T& ) const;
    };
    // file handle.cpp
    #include <iostream>
    #include "handle.h"
    template<typename T>
    void handle<T>::fun( const T& obj ) const
    {
        std::cout << obj << '\n';
    }
    // qui seguono le dichiarazioni di tutti i tipi per cui la classe
    // sarà istanziata
    template class handle<const int>;
    template class handle<const char*>;
    // file main.cpp
    #include "handle.h"
    int main()
    {
        const int x = 999;
        const char* s = "abc";
        handle<const int> h1;
        handle<const char*> h2;
        h1.fun( x );
        h2.fun( s );
    }
    Se però volessi dichiarare e definire su files separati funzioni
    'friend template' la semplice trovata di cui sopra non è più
    sufficiente per il linker che continua a dare errori.
    La soluzione in questo caso è un po' più complessa della precedente,
    tanto che qualcuno preferisce lasciare la definizione delle funzioni
    friend template nel corpo della template class stessa.
    Per i casi in cui è richiesto di separare dichiarazione e
    definizione su files separati esite comunque una soluzione come da
    esempio seguente. Ponete attenzione alle righe commentate:
    // file templates.h
    #ifndef _TMPLT_
    #define _TMPLT_
    #include <iostream>
    // bisogna pre-dichiarare la classe stessa
    template <typename T> class my_class;
    // quindi la friend template
    template <typename T>
    std::ostream& operator<<( std::ostream& out,
                              const my_class<T>& obj );
    template <typename T>
    class my_class
    {
    public:
        my_class( const T& v );
    private:
    // ...e, per ultimo, inserire il simbolo <> prima della parentesi
        friend std::ostream& operator<< <> ( std::ostream& out,
                                             const my_class<T>& obj );
        const T val;
    };
    #endif
    // file templates.cpp
    #include "templates.h"
    // le seguenti sono le dichiarazioni di istanza esplicita (vedi
    // soluzione precedente)
    template class my_class<int>;
    template class my_class<char*>;
    // e questa è specifica per la funzione che ci interessa
    // ricordo che le funzioni membro non hanno bisogno di essere
    // instanziate per ogni tipo
    template std::ostream& operator<<( std::ostream& out,
                                       const my_class<int> &obj );
    template std::ostream& operator<<( std::ostream& out,
                                       const my_class<char*> &obj );
    template <typename T>
    my_class<T>::my_class( const T& v = T() )
        : val( v )
    { }
    template <typename T>
    inline std::ostream& operator<<( std::ostream &out,
                                     const my_class<T> &obj )
    {
        return out << obj.val << '\n';
    }
    // file main.cpp
    #include "templates.h"
    int main()
    {
        my_class<int> h1(999);
        std::cout << h1;
        my_class<char*> h2("abc");
        std::cout << h2;
        return 0;
    }
    L'esempio è completo e può essere compilato cosi come si trova.
    Ripeto il concetto che per tutte le funzioni membro sono sufficenti
    solo le istanze esplicite di classe per ogni tipo, quindi non è
    necessario scrivere le instanze di funzione come fatto sopra per le
    funzioni friend templates (vedi soluzione precedente).
11) Come si passa un array ad una funzione in C++?
R)  In C++ un array non puo` essere passato come parametro allo
    stesso modo di una struttura o un altro aggregato.
    Sebbene sia possibile dichiarare la funzione nel seguente modo:
    const size_t Size = 100;
    void MyFunc(T array[Size]);
    in C (e di conseguenza anche in C++) un parametro di tipo array
    di T decade a puntatore a T e Size perde di significato cosicche`
    e` possibile scrivere
    T MyArray[Size/2];
    MyFunc(MyArray);   // con tutte le conseguenze del caso
    Il modo classico in C/C++ di passare un array come parametro
    e` quello di passare un puntatore al primo elemento e la
    dimensione dell'array:
    void MyFunc(T* Array, size_t ArraySize) {
      for(size_t i=0; i<ArraySize; ++i)
        std::cout << Array[i] << std::endl;
    }
    Questo metodo si applica sia ad array statici che array
    allocati dinamicamente:
    int main() {
      const size_t Size = 100;
      T MyArray[Size];
      T* MyDynArray = new T[Size];
      MyFunc(MyArray, Size);
      MyFunc(MyDynArray, Size);
      return 0;
    }
    Gli array (come tutti gli altri tipi di dati) possono anche essere
    passati per reference:
    void MyFunc(T (&Array)[], size_t ArraySize) {
      for(size_t i=0; i<ArraySize; ++i)
        std::cout << Array[i] << std::endl;
    }
    Una soluzione alternativa ed elegante e` quella di utilizzare i
    template e la deduzione implicita dei parametri, ma richiede un
    compilatore standard (o almeno sufficientemente standard):
    template<typename T, size_t Size>
    void MyFunc(T (&Array)[Size])  {
      for(size_t i=0; i<Size; ++i)
        std::cout << Array[i] << std::endl;
    }
    int main() {
      int Array1[5];
      int Array2[100];
      MyFunc(Array1);
      MyFunc(Array2);
      return 0;
    }
    Infine una soluzione quasi sempre molto valida e` quella di
    utilizzare la classe std::vector<> al posto dei tradizionali
    array:
    typedef std::vector<int> ArrayOfInt;
    void MyFunc(ArrayOfInt& array);
    ArrayOfInt MyArray;
    MyFunc(MyArray);    // passaggio di un array
12) Come posso generare numeri casuali?
R)  La libreria standard del C (e quindi del C++) prevede le
    funzioni srand() e rand().
    La prima serve a inizializzare il generatore di numeri casuali,
    la seconda invece restituisce un numero casuale nell'intervallo
    0..RAND_MAX. Se vuoi ottenere valori inferiori a RAND_MAX
    e` importante non utilizzare l'operatore di modulo:
    int random_fra_0_e_99() {
      return rand() % 100;
    }
    poiche` in questo modo otterresti una sequenza di qualita`
    assai scarsa... molto meglio utilizzare
    int un_po_meglio_fra_0_e_99() {
      static const double divisore = (1.0 + RAND_MAX)/100.0;
      return static_cast<int>(rand()/divisore);
    }
    RAND_MAX, srand() e rand() sono dichiarate in stdlib.h
13) Come mai ottengo sempre la stessa sequenza di numeri casuali?
R)  Ti sei ricordato di effettuare l'inizializzazione del generatore
    di numeri casuali? Hai evitato di inizializzarlo sempre con
    lo stesso seme? Un buon modo di fare tutto cio` e`:
    #include <stdlib.h>
    #include <time.h>
    /* ... */
    srand(static_cast<unsigned>(time(0)));
14) La sequenza generata da rand() non e` molto buona, dove posso
    trovare generatori di numeri casuali piu` validi?
R)  Il generatore fornito dalla libreria standard non e` solitamente
    di alta qualita`, anche se ha il pregio di essere veloce... Se hai
    esigenze piu` spinte, questo piccolo elenco comprende sia testi
    di teoria, sia software gia` fatto, sia informazioni sui
    generatori hardware (non pseudo, ma VERI numeri casuali)
    accessibili via rete.
 
http://csep1.phy.ornl.gov/rn/rn.html
 
http://random.mat.sbg.ac.at/
 
http://www.math.keio.ac.jp/~matumoto/emt.html
 
http://www.taygeta.com/random.xml
 
http://www.fourmilab.ch/hotbits/
 
http://random.mat.sbg.ac.at/ftp/pub/data/winrand.zip
 
http://webnz.com/robert/nzc_nr02.html
 
http://www.math.keio.ac.jp/~matumoto/emt.html
15) Che differenza c'e` tra STL e la libreria standard del C++?
R)  La libreria standard del C++ trae spunto da STL, il lavoro
    sviluppato da Alexander Stepanov. Molte delle funzionalita`
    offerte da STL sono state inserite nella libreria del C++,
    tuttavia la libreria del C++ non e` STL.
    STL rimane un progetto a se stante e in continua evoluzione,
    mentre il contenuto della libreria standard del C++ e` deciso
    unicamente dal comitato ANSI/ISO.
16) Lavorando con i numeri in virgola mobile, non riesco ad ottenere
    risultati precisi, perche`?
R)  E` normale, la rappresentazione dei numeri reali in base (base 10,
    base 2,...) e con un numero finito di cifre comporta inerentemente
    un errore di approssimazione. Ad esempio 1/3 in base 10 non puo`
    essere rappresentato con un numero finito di cifre, 1/10 che in
    base 10 equivale a 0.1, in base 2 e` periodico (proprio come 1/3
    in base 10).
    Infine ci sono anche i numeri irrazionali (es. sqrt(3)) che per
    loro natura non sono mai rappresentabili con precisione in alcuna
    base.
    Cio` significa che lavorando con i numeri reali devi sempre
    aspettarti risultati affetti da errori di approssimazione. Tali
    errori possono essere anche molto significativi poiche` le
    operazioni aritmetiche tendono ad amplificarli.
    Per maggiori riferimenti, puoi leggere
    "Introduzione alla matematica computazionale"
    di R. Bevilacqua, D. Bini, M. Capovani, O. Menchi
    edito da Zanichelli
17) a - void main() funziona perché non dovrei usarlo?
    b - Posso omettere di scrivere uno statement return in main?
    c - Posso scrivere una main ricorsiva?
R)  a - le due definizioni garantite valide di main secondo lo standard
        sono:
        int main()
        int main(int argc, char* argv[])
        la prima è naturalmente riscrivibile in
        int main(void)
        ma questo è uno stile C che è preferibile non usare in C++.
        Il vostro compilatore può permettervi altre forme di
        dichiarazione di main. Non usatele, non avete alcun buon motivo
        per farlo.
    b - si, è espressamente garantito che se il controllo raggiunge la
        fine di main senza incontrare un return l'effetto sarà quello di
        eseguire return 0;
    c - no, è esplicitamente vietato [3.6.1 dello standard].
18) Posso ereditare pubblicamente da una classe che non ha distruttore
    virtuale?
    Risposta breve: No.
    Regola d'oro  : si eredita pubblicamente soltanto da classi con
                    distruttore public virtuale o protected non-virtual
    Perché:
    struct base{ };
    struct derivata: public base{ };
    int main(){ base* unaBase = new derivata; delete unaBase; }
    Deletare polimorficamente una classe senza ditruttore virtuale porta
    ad un comportamento indefinito [5.3.5.3 dello standard].
    Se state pensando che non userete mai una delete in modo polimorfico
    e ritenete quindi di essere nella legalità, avete ragione: è legale
    ma immorale: state violando il principio di sostituzione di Liskov.
19) a - Come si sviluppano programmi con interfaccia utente grafica?
    b - E programmi con interfaccia a caratteri, ma a schermo pieno
        invece che linea per linea?
R)  a - Il linguaggio C++ standard non supporta lo sviluppo di programmi
        dotati di GUI, perche' non esiste una libreria GUI standard e
        perche' il linguaggio e' pensato per poter essere implementato
        anche su sistemi non dotati di terminale interattivo. Esistono
        pero' librerie in grado di supportare la programmazione di
        interfacce grafiche. Di tali librerie, alcune sono fornite con
        il sistema operativo, altre con particolari ambienti di
        sviluppo, altre sono sviluppate separatamente dagli ambienti di
        sviluppo ma supportano un solo ambiente di sviluppo, altre sono
        multipiattaforma. Tuttavia, sono tutte librerie non standard.
    b - Vale lo stesso discorso delle GUI; esistono solo librerie
        proprietarie, o comunque limitate a specifiche piattaforme.
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

========================================================================
                  F.A.Q. UFFICIALI DI IT.COMP.LANG.C++
                       revisione 1.7 - 25/01/2005
           a cura di diversi partecipanti di it.comp.lang.c++
      Revisione più recente: 
http://www.emagsoftware.it/faqcpp.txt
========================================================================
Indice delle domande:





















========================================================================





 
http://www.news.nic.it/manif/it.comp.lang.c%2B%2B.html













   DJGPP - 
http://www.delorie.com/djgpp

   Cygwin - 
http://www.cygwin.com

   Mingw - 
http://www.mingw.org/


 
http://msdn.microsoft.com/visualc/vctoolkit2003/
 
http://www.intel.com/software/products/noncom/


   QEdit



   WinEdit - 
http://www.winedit.com

   UltraEdit - 
http://www.ultraedit.com

   MultiEdit - 
http://www.multiedit.com

   EditPlus - 
http://www.editplus.com

   Texturizer - 
http://www.texturizer.net/

   PFE - 
http://www.lancs.ac.uk/people/cpaap/pfe/

   KDevelop - 
http://www.kdevelop.org

   CForge - 
http://www.codeforge.com

   VIM - 
http://www.vim.org




   (molto piu` costosa) all'indirizzo 
http://webstore.ansi.org
, oppure
   ancora in forma di libro rilegato all'indirizzo
 
http://eu.wiley.com/WileyCDA/WileyTitle/productCd-0470846747.html
   Se hai già acquistato la versione precedente dello standard, in
questo
   corposo documento puoi trovare tutte le variazioni:
 
http://www.acceleratedcpp.com/authors/koenig/c++std/revisions.pdf
