From 4e28ec0efdc127b51930aaa8de4f92e08c66011f Mon Sep 17 00:00:00 2001 From: robertmargelli Date: Tue, 5 May 2015 21:21:53 -0700 Subject: new C++ it version --- it-it/c++-it.html.markdown | 597 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 597 insertions(+) create mode 100644 it-it/c++-it.html.markdown (limited to 'it-it/c++-it.html.markdown') diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown new file mode 100644 index 00000000..8914c234 --- /dev/null +++ b/it-it/c++-it.html.markdown @@ -0,0 +1,597 @@ +--- +language: c++ +filename: learncpp.cpp +contributors: + - ["Steven Basart", "http://github.com/xksteven"] + - ["Matt Kline", "https://github.com/mrkline"] +translators: + - ["Robert Margelli", "http://github.com/sinkswim/"] +lang: it-it +--- + +Il C++ e' un linguaggio di programmazione il quale, +[secondo il suo inventore Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote), +e' stato progettato per + +- essere un "miglior C" +- supportare l'astrazione dei dati +- supportare la programmazione orientata agli oggetti +- supportare la programmazione generica + +Nonostante la sintassi possa risultare piu' difficile o complessa di linguaggi piu' recenti, +e' usato in maniera vasta poiche' viene compilato in istruzioni macchina che possono +essere eseguite direttamente dal processore ed offre un controllo stretto sull'hardware (come il linguaggio C) +ed allo stesso tempo offre caratteristiche ad alto livello come i generici, le eccezioni, e le classi. +Questa combinazione di velocita' e funzionalita' rende il C++ +uno dei piu' utilizzati linguaggi di programmazione. + +```c++ +////////////////// +// Confronto con il C +////////////////// + +// Il C++ e' _quasi_ un superset del C e con esso condivide la sintassi di base per +// la dichiarazione di variabili, tipi primitivi, e funzioni. + +// Proprio come nel C, l'inizio del programma e' una funzione chiamata +// main con un intero come tipo di ritorno, +// nonostante void main() sia anch'essa accettata dalla maggior parte dei compilatori(gcc, clang, ecc...) +// Questo valore serve come stato d'uscita del programma. +// Vedi http://it.wikipedia.org/wiki/Valore_di_uscita per maggiori informazioni. +int main(int argc, char** argv) +{ + // Gli argomenti a linea di comando sono passati tramite argc e argv cosi' come + // avviene in C. + // argc indica il numero di argomenti, + // e argv e' un array in stile-C di stringhe (char*) + // che rappresenta gl iargomenti. + // Il primo argomento e' il nome che e' stato assegnato al programma. + // argc e argv possono essere omessi se non hai bisogno di argomenti, + // in questa maniera la funzione avra' int main() come firma. + + // Lo stato di uscita 0 indica successo. + return 0; +} + +// Tuttavia, il C++ varia nei seguenti modi: + +// In C++, i caratteri come letterali sono da un byte. +sizeof('c') == 1 + +// In C, i caratteri come letterali sono della stessa dimensione degli interi. +sizeof('c') == sizeof(10) + + +// C++ ha prototipizzazione rigida +void func(); // funziona che non accetta argomenti + +// In C +void func(); // funzione che puo' accettare un qualsiasi numero di argomenti + +// Usa nullptr invece di NULL in C++ +int* ip = nullptr; + +// Gli header C standard sono disponibili in C++, +// ma sono prefissati con "c" e non hanno il suffisso ".h". +#include + +int main() +{ + printf("Ciao, mondo!\n"); + return 0; +} + +/////////////////////////////// +// Overloading per le funzioni +////////////////////////////// + +// Il C++ supporta l'overloading per le funzioni +// sia dato che ogni funzione accetta parametri diversi. + +void print(char const* myString) +{ + printf("Stringa %s\n", myString); +} + +void print(int myInt) +{ + printf("Il mio int e' %d", myInt); +} + +int main() +{ + print("Ciao"); // Viene chiamata void print(const char*) + print(15); // Viene chiamata void print(int) +} + +//////////////////////// +// Argomenti di default +/////////////////////// + +// Puoi fornire argomenti di default per una funzione +// se non sono forniti dal chiamante. + +void faiQualcosaConInteri(int a = 1, int b = 4) +{ + // fai qualcosa con gli interi qui +} + +int main() +{ + faiQualcosaConInteri(); // a = 1, b = 4 + faiQualcosaConInteri(20); // a = 20, b = 4 + faiQualcosaConInteri(20, 5); // a = 20, b = 5 +} + +// Gli argomenti di default devono essere alla fine della lista degli argomenti. + +void dichiarazioneInvalida(int a = 1, int b) // Errore! +{ +} + + +///////////// +// Namespaces +///////////// + +// I namespaces forniscono visibilita' separata per dichiarazioni di variabili, funzioni, +// ed altro. +// I namespaces possono essere annidati. + +namespace Primo { + namespace Annidato { + void foo() + { + printf("Questa e' Primo::Annidato::foo\n"); + } + } // fine di namespace Annidato +} // fine di namespace Primo + +namespace Secondo { + void foo() + { + printf("Questa e' Secondo::foo\n") + } +} + +void foo() +{ + printf("Questa e' foo globale\n"); +} + +int main() +{ + // Assume che tutto venga dal namespace "Secondo" + // a meno che non venga dichiarato altrimenti. + using namespace Secondo; + + foo(); // stampa "Questa e' Secondo::foo" + Primo::Annidato::foo(); // stampa "Questa e' Primo::Annidato::foo" + ::foo(); // stampa "Questa e' foo globale" +} + +/////////////// +// Input/Output +/////////////// + +// L'input e l'output in C++ utilizza gli streams +// cin, cout, e cerr i quali rappresentano stdin, stdout, e stderr. +// << e' l'operatore di inserzione >> e' l'operatore di estrazione. + +#include // Include for I/O streams + +using namespace std; // Gli streams sono nel namespace std (libreria standard) + +int main() +{ + int myInt; + + // Stampa su stdout (o terminalee/schermo) + cout << "Inserisci il tuo numero preferito:\n"; + // Prende l'input + cin >> myInt; + + // cout puo' anche essere formattato + cout << "Il tuo numero preferito e' " << myInt << "\n"; + // stampa "Il tuo numero preferito e' " + + cerr << "Usato per messaggi di errore"; +} + +//////////// +// Stringhe +/////////// + +// Le stringhe in C++ sono oggetti ed hanno molte funzioni membro +#include + +using namespace std; // Anche le stringhe sono contenute nel namespace std (libreria standard) + +string myString = "Ciao"; +string myOtherString = " Mondo"; + +// + e' usato per la concatenazione. +cout << myString + myOtherString; // "Ciao Mondo" + +cout << myString + " Bella"; // "Ciao Bella" + +// le stringhe in C++ possono essere modificate. +myString.append(" Mario"); +cout << myString; // "Ciao Mario" + + +/////////////// +// Riferimenti +////////////// + +// Oltre ai puntatori come quelli in C, +// il C++ ha i _riferimenti_. +// Questi non sono tipi puntatori che non possono essere riassegnati una volta settati +// e non possono essere null. +// Inoltre, essi hanno la stessa sintassi della variabile stessa: +// * non e' necessario per la dereferenziazione e +// & ("indirizzo di") non e' usato per l'assegnamento. + +using namespace std; + +string foo = "Io sono foo"; +string bar = "Io sono bar"; + + +string& fooRef = foo; // Questo crea un riferimento a foo. +fooRef += ". Ciao!"; // Modifica foo attraverso il riferimento +cout << fooRef; // Stampa "Io sono foo. Ciao!" + +// Non riassegna "fooRef". Questo e' come scrivere "foo = bar", e +// foo == "Io sono bar" +// dopo questa riga. +fooRef = bar; + +const string& barRef = bar; // Crea un riferimento const a bar. +// Come in C, i valori const (i puntatori e i riferimenti) non possono essere modificati. +barRef += ". Ciao!"; // Errore, i riferimenti const non possono essere modificati. + +////////////////////////////////////////////////// +// Classi e programmazione orientata agli oggetti +///////////////////////////////////////////////// + +// Primo esempio delle classi +#include + +// Dichiara una classe. +// Le classi sono in genere dichiara in un header file (.h o .hpp). +class Cane { + // Variabili e funzioni membro sono private di default. + std::string nome; + int peso; + +// Tutti i membri dopo questo sono pubblici (public) +// finche' "private:" o "protected:" non compaiono. +public: + + // Costruttore di default + Cane(); + + // Dichiarazioni di funzioni membro (le implentazioni sono a seguito) + // Nota che stiamo usando std::string invece di porre + // using namespace std; + // sopra. + // Mai usare uno statement "using namespace" in uno header. + void impostaNome(const std::string& nomeCane); + + void impostaPeso(int pesoCane); + + // Le funzioni che non modificano lo stato dell'oggetto + // dovrebbero essere marcate come const. + // Questo permette di chiamarle con un riferimento const all'oggetto. + // Inoltre, nota che le funzioni devono essere dichiarate espliciamente come _virtual_ + // per essere sovrascritte in classi derivate. + // Le funzioni non sono virtual di default per motivi di performance. + virtual void print() const; + + // Le funzioni possono essere definite anche all'interno del corpo della classe. + // Le funzioni definite in questo modo sono automaticamente inline. + void abbaia() const { std::cout << nome << " abbaia!\n"; } + + // Assieme con i costruttori, il C++ fornisce i distruttori. + // Questi sono chiamati quando un oggetto e' rimosso o esce dalla visibilita'. + // Questo permette paradigmi potenti come il RAII + // (vedi sotto) + // I distruttori devono essere virtual per permettere a classi di essere derivate da questa. + virtual ~Dog(); + +}; // Un punto e virgola deve seguire la definizione della funzione + +// Class member functions are usually implemented in .cpp files. +void Dog::Dog() +{ + std::cout << "A dog has been constructed\n"; +} + +// Objects (such as strings) should be passed by reference +// if you are modifying them or const reference if you are not. +void Dog::setName(const std::string& dogsName) +{ + name = dogsName; +} + +void Dog::setWeight(int dogsWeight) +{ + weight = dogsWeight; +} + +// Notice that "virtual" is only needed in the declaration, not the definition. +void Dog::print() const +{ + std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; +} + +void Dog::~Dog() +{ + cout << "Goodbye " << name << "\n"; +} + +int main() { + Dog myDog; // prints "A dog has been constructed" + myDog.setName("Barkley"); + myDog.setWeight(10); + myDog.printDog(); // prints "Dog is Barkley and weighs 10 kg" + return 0; +} // prints "Goodbye Barkley" + +// Inheritance: + +// This class inherits everything public and protected from the Dog class +class OwnedDog : public Dog { + + void setOwner(const std::string& dogsOwner) + + // Override the behavior of the print function for all OwnedDogs. See + // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping + // for a more general introduction if you are unfamiliar with + // subtype polymorphism. + // The override keyword is optional but makes sure you are actually + // overriding the method in a base class. + void print() const override; + +private: + std::string owner; +}; + +// Meanwhile, in the corresponding .cpp file: + +void OwnedDog::setOwner(const std::string& dogsOwner) +{ + owner = dogsOwner; +} + +void OwnedDog::print() const +{ + Dog::print(); // Call the print function in the base Dog class + std::cout << "Dog is owned by " << owner << "\n"; + // Prints "Dog is and weights " + // "Dog is owned by " +} + +////////////////////////////////////////// +// Initialization and Operator Overloading +////////////////////////////////////////// + +// In C++ you can overload the behavior of operators such as +, -, *, /, etc. +// This is done by defining a function which is called +// whenever the operator is used. + +#include +using namespace std; + +class Point { +public: + // Member variables can be given default values in this manner. + double x = 0; + double y = 0; + + // Define a default constructor which does nothing + // but initialize the Point to the default value (0, 0) + Point() { }; + + // The following syntax is known as an initialization list + // and is the proper way to initialize class member values + Point (double a, double b) : + x(a), + y(b) + { /* Do nothing except initialize the values */ } + + // Overload the + operator. + Point operator+(const Point& rhs) const; + + // Overload the += operator + Point& operator+=(const Point& rhs); + + // It would also make sense to add the - and -= operators, + // but we will skip those for brevity. +}; + +Point Point::operator+(const Point& rhs) const +{ + // Create a new point that is the sum of this one and rhs. + return Point(x + rhs.x, y + rhs.y); +} + +Point& Point::operator+=(const Point& rhs) +{ + x += rhs.x; + y += rhs.y; + return *this; +} + +int main () { + Point up (0,1); + Point right (1,0); + // This calls the Point + operator + // Point up calls the + (function) with right as its paramater + Point result = up + right; + // Prints "Result is upright (1,1)" + cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; + return 0; +} + +//////////////////////////// +// Gestione delle eccezioni +/////////////////////////// + +// La libreria standard fornisce un paio di tipi d'eccezioni +// (vedi http://en.cppreference.com/w/cpp/error/exception) +// ma ogni tipo puo' essere lanciato come eccezione +#include + +// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi +// handlers _catch_. +try { + // Non allocare eccezioni nello heap usando _new_. + throw std::exception("E' avvenuto un problema"); +} +// Cattura le eccezioni come riferimenti const se sono oggetti +catch (const std::exception& ex) +{ + std::cout << ex.what(); +// Cattura ogni eccezioni non catturata dal blocco _catch_ precedente +} catch (...) +{ + std::cout << "Catturata un'eccezione sconosciuta"; + throw; // Rilancia l'eccezione +} + +/////// +// RAII +/////// + +// RAII sta per Resource Allocation Is Initialization. +// Spesso viene considerato come il piu' potente paradigma in C++. +// E' un concetto semplice: un costruttore di un oggetto +// acquisisce le risorse di tale oggetto ed il distruttore le rilascia. + +// Per comprendere come questo sia vantaggioso, +// consideriamo una funzione che usa un gestore di file in C: +void faiQualcosaConUnFile(const char* nomefile) +{ + // Per cominciare, assumiamo che niente possa fallire. + + FILE* fh = fopen(nomefile, "r"); // Apri il file in modalita' lettura. + + faiQualcosaConUnFile(fh); + faiQualcosAltroConEsso(fh); + + fclose(fh); // Chiudi il gestore di file. +} + +// Unfortunately, things are quickly complicated by error handling. +// Suppose fopen can fail, and that doSomethingWithTheFile and +// doSomethingElseWithIt return error codes if they fail. +// (Exceptions are the preferred way of handling failure, +// but some programmers, especially those with a C background, +// disagree on the utility of exceptions). +// We now have to check each call for failure and close the file handle +// if a problem occurred. +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Open the file in read mode + if (fh == nullptr) // The returned pointer is null on failure. + return false; // Report that failure to the caller. + + // Assume each function returns false if it failed + if (!doSomethingWithTheFile(fh)) { + fclose(fh); // Close the file handle so it doesn't leak. + return false; // Propagate the error. + } + if (!doSomethingElseWithIt(fh)) { + fclose(fh); // Close the file handle so it doesn't leak. + return false; // Propagate the error. + } + + fclose(fh); // Close the file handle so it doesn't leak. + return true; // Indicate success +} + +// C programmers often clean this up a little bit using goto: +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); + if (fh == nullptr) + return false; + + if (!doSomethingWithTheFile(fh)) + goto failure; + + if (!doSomethingElseWithIt(fh)) + goto failure; + + fclose(fh); // Close the file + return true; // Indicate success + +failure: + fclose(fh); + return false; // Propagate the error +} + +// If the functions indicate errors using exceptions, +// things are a little cleaner, but still sub-optimal. +void doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Open the file in read mode + if (fh == nullptr) + throw std::exception("Could not open the file."); + + try { + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + } + catch (...) { + fclose(fh); // Be sure to close the file if an error occurs. + throw; // Then re-throw the exception. + } + + fclose(fh); // Close the file + // Everything succeeded +} + +// Compare this to the use of C++'s file stream class (fstream) +// fstream uses its destructor to close the file. +// Recall from above that destructors are automatically called +// whenever an object falls out of scope. +void doSomethingWithAFile(const std::string& filename) +{ + // ifstream is short for input file stream + std::ifstream fh(filename); // Open the file + + // Do things with the file + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + +} // The file is automatically closed here by the destructor + +// This has _massive_ advantages: +// 1. No matter what happens, +// the resource (in this case the file handle) will be cleaned up. +// Once you write the destructor correctly, +// It is _impossible_ to forget to close the handle and leak the resource. +// 2. Note that the code is much cleaner. +// The destructor handles closing the file behind the scenes +// without you having to worry about it. +// 3. The code is exception safe. +// An exception can be thrown anywhere in the function and cleanup +// will still occur. + +// All idiomatic C++ code uses RAII extensively for all resources. +// Additional examples include +// - Memory using unique_ptr and shared_ptr +// - Containers - the standard library linked list, +// vector (i.e. self-resizing array), hash maps, and so on +// all automatically destroy their contents when they fall out of scope. +// - Mutexes using lock_guard and unique_lock +``` +Letture consigliate: + +Un riferimento aggiornato del linguaggio puo' essere trovato qui + + +Risorse addizionali possono essere trovate qui -- cgit v1.2.3 From 763e7eb224fce450cbf35004d4a5e11e57198cf0 Mon Sep 17 00:00:00 2001 From: robertmargelli Date: Wed, 6 May 2015 11:09:31 -0700 Subject: added and finished C++-it --- it-it/c++-it.html.markdown | 370 ++++++++++++++++++++++----------------------- 1 file changed, 185 insertions(+), 185 deletions(-) (limited to 'it-it/c++-it.html.markdown') diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown index 8914c234..429c976f 100644 --- a/it-it/c++-it.html.markdown +++ b/it-it/c++-it.html.markdown @@ -9,45 +9,45 @@ translators: lang: it-it --- -Il C++ e' un linguaggio di programmazione il quale, +Il C++ è un linguaggio di programmazione il quale, [secondo il suo inventore Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote), -e' stato progettato per +è stato progettato per - essere un "miglior C" - supportare l'astrazione dei dati - supportare la programmazione orientata agli oggetti - supportare la programmazione generica -Nonostante la sintassi possa risultare piu' difficile o complessa di linguaggi piu' recenti, -e' usato in maniera vasta poiche' viene compilato in istruzioni macchina che possono +Nonostante la sintassi possa risultare più difficile o complessa di linguaggi più recenti, +è usato in maniera vasta poichè viene compilato in istruzioni macchina che possono essere eseguite direttamente dal processore ed offre un controllo stretto sull'hardware (come il linguaggio C) ed allo stesso tempo offre caratteristiche ad alto livello come i generici, le eccezioni, e le classi. -Questa combinazione di velocita' e funzionalita' rende il C++ -uno dei piu' utilizzati linguaggi di programmazione. +Questa combinazione di velocità e funzionalità rende il C++ +uno dei più utilizzati linguaggi di programmazione. ```c++ ////////////////// // Confronto con il C ////////////////// -// Il C++ e' _quasi_ un superset del C e con esso condivide la sintassi di base per +// Il C++ è _quasi_ un superset del C e con esso condivide la sintassi di base per // la dichiarazione di variabili, tipi primitivi, e funzioni. -// Proprio come nel C, l'inizio del programma e' una funzione chiamata +// Proprio come nel C, l'inizio del programma è una funzione chiamata // main con un intero come tipo di ritorno, // nonostante void main() sia anch'essa accettata dalla maggior parte dei compilatori(gcc, clang, ecc...) // Questo valore serve come stato d'uscita del programma. // Vedi http://it.wikipedia.org/wiki/Valore_di_uscita per maggiori informazioni. int main(int argc, char** argv) { - // Gli argomenti a linea di comando sono passati tramite argc e argv cosi' come + // Gli argomenti a linea di comando sono passati tramite argc e argv così come // avviene in C. // argc indica il numero di argomenti, - // e argv e' un array in stile-C di stringhe (char*) + // e argv è un array in stile-C di stringhe (char*) // che rappresenta gl iargomenti. - // Il primo argomento e' il nome che e' stato assegnato al programma. + // Il primo argomento è il nome che è stato assegnato al programma. // argc e argv possono essere omessi se non hai bisogno di argomenti, - // in questa maniera la funzione avra' int main() come firma. + // in questa maniera la funzione avrà int main() come firma. // Lo stato di uscita 0 indica successo. return 0; @@ -66,7 +66,7 @@ sizeof('c') == sizeof(10) void func(); // funziona che non accetta argomenti // In C -void func(); // funzione che puo' accettare un qualsiasi numero di argomenti +void func(); // funzione che può accettare un qualsiasi numero di argomenti // Usa nullptr invece di NULL in C++ int* ip = nullptr; @@ -95,7 +95,7 @@ void print(char const* myString) void print(int myInt) { - printf("Il mio int e' %d", myInt); + printf("Il mio int è %d", myInt); } int main() @@ -134,7 +134,7 @@ void dichiarazioneInvalida(int a = 1, int b) // Errore! // Namespaces ///////////// -// I namespaces forniscono visibilita' separata per dichiarazioni di variabili, funzioni, +// I namespaces forniscono visibilità separata per dichiarazioni di variabili, funzioni, // ed altro. // I namespaces possono essere annidati. @@ -142,7 +142,7 @@ namespace Primo { namespace Annidato { void foo() { - printf("Questa e' Primo::Annidato::foo\n"); + printf("Questa è Primo::Annidato::foo\n"); } } // fine di namespace Annidato } // fine di namespace Primo @@ -150,13 +150,13 @@ namespace Primo { namespace Secondo { void foo() { - printf("Questa e' Secondo::foo\n") + printf("Questa è Secondo::foo\n") } } void foo() { - printf("Questa e' foo globale\n"); + printf("Questa è foo globale\n"); } int main() @@ -165,9 +165,9 @@ int main() // a meno che non venga dichiarato altrimenti. using namespace Secondo; - foo(); // stampa "Questa e' Secondo::foo" - Primo::Annidato::foo(); // stampa "Questa e' Primo::Annidato::foo" - ::foo(); // stampa "Questa e' foo globale" + foo(); // stampa "Questa è Secondo::foo" + Primo::Annidato::foo(); // stampa "Questa è Primo::Annidato::foo" + ::foo(); // stampa "Questa è foo globale" } /////////////// @@ -176,7 +176,7 @@ int main() // L'input e l'output in C++ utilizza gli streams // cin, cout, e cerr i quali rappresentano stdin, stdout, e stderr. -// << e' l'operatore di inserzione >> e' l'operatore di estrazione. +// << è l'operatore di inserzione >> è l'operatore di estrazione. #include // Include for I/O streams @@ -191,9 +191,9 @@ int main() // Prende l'input cin >> myInt; - // cout puo' anche essere formattato - cout << "Il tuo numero preferito e' " << myInt << "\n"; - // stampa "Il tuo numero preferito e' " + // cout può anche essere formattato + cout << "Il tuo numero preferito è " << myInt << "\n"; + // stampa "Il tuo numero preferito è " cerr << "Usato per messaggi di errore"; } @@ -210,7 +210,7 @@ using namespace std; // Anche le stringhe sono contenute nel namespace std (libr string myString = "Ciao"; string myOtherString = " Mondo"; -// + e' usato per la concatenazione. +// + è usato per la concatenazione. cout << myString + myOtherString; // "Ciao Mondo" cout << myString + " Bella"; // "Ciao Bella" @@ -229,8 +229,8 @@ cout << myString; // "Ciao Mario" // Questi non sono tipi puntatori che non possono essere riassegnati una volta settati // e non possono essere null. // Inoltre, essi hanno la stessa sintassi della variabile stessa: -// * non e' necessario per la dereferenziazione e -// & ("indirizzo di") non e' usato per l'assegnamento. +// * non è necessario per la dereferenziazione e +// & ("indirizzo di") non è usato per l'assegnamento. using namespace std; @@ -242,7 +242,7 @@ string& fooRef = foo; // Questo crea un riferimento a foo. fooRef += ". Ciao!"; // Modifica foo attraverso il riferimento cout << fooRef; // Stampa "Io sono foo. Ciao!" -// Non riassegna "fooRef". Questo e' come scrivere "foo = bar", e +// Non riassegna "fooRef". Questo è come scrivere "foo = bar", e // foo == "Io sono bar" // dopo questa riga. fooRef = bar; @@ -266,7 +266,7 @@ class Cane { int peso; // Tutti i membri dopo questo sono pubblici (public) -// finche' "private:" o "protected:" non compaiono. +// finchè "private:" o "protected:" non compaiono. public: // Costruttore di default @@ -294,7 +294,7 @@ public: void abbaia() const { std::cout << nome << " abbaia!\n"; } // Assieme con i costruttori, il C++ fornisce i distruttori. - // Questi sono chiamati quando un oggetto e' rimosso o esce dalla visibilita'. + // Questi sono chiamati quando un oggetto è rimosso o esce dalla visibilità. // Questo permette paradigmi potenti come il RAII // (vedi sotto) // I distruttori devono essere virtual per permettere a classi di essere derivate da questa. @@ -302,122 +302,122 @@ public: }; // Un punto e virgola deve seguire la definizione della funzione -// Class member functions are usually implemented in .cpp files. -void Dog::Dog() +// Le funzioni membro di una classe sono generalmente implementate in files .cpp . +void Cane::Cane() { - std::cout << "A dog has been constructed\n"; + std::cout << "Un cane è stato costruito\n"; } -// Objects (such as strings) should be passed by reference -// if you are modifying them or const reference if you are not. -void Dog::setName(const std::string& dogsName) +// Gli oggetti (ad esempio le stringhe) devono essere passati per riferimento +// se li stai modificando o come riferimento const altrimenti. +void Cane::impostaNome(const std::string& nomeCane) { - name = dogsName; + nome = nomeCane; } -void Dog::setWeight(int dogsWeight) +void Cane::impostaPeso(int pesoCane) { - weight = dogsWeight; + peso = pesoCane; } -// Notice that "virtual" is only needed in the declaration, not the definition. -void Dog::print() const +// Notare che "virtual" è solamente necessario nelle dichiarazioni, non nelle definizioni. +void Cane::print() const { - std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; + std::cout << "Il cane è " << nome << " e pesa " << peso << "kg\n"; } -void Dog::~Dog() +void Cane::~Cane() { - cout << "Goodbye " << name << "\n"; + cout << "Ciao ciao " << nome << "\n"; } int main() { - Dog myDog; // prints "A dog has been constructed" - myDog.setName("Barkley"); - myDog.setWeight(10); - myDog.printDog(); // prints "Dog is Barkley and weighs 10 kg" + Cane myDog; // stampa "Un cane è stato costruito" + myDog.impostaNome("Barkley"); + myDog.impostaPeso(10); + myDog.print(); // stampa "Il cane è Barkley e pesa 10 kg" return 0; -} // prints "Goodbye Barkley" +} // stampa "Ciao ciao Barkley" -// Inheritance: +// Ereditarietà: -// This class inherits everything public and protected from the Dog class -class OwnedDog : public Dog { +// Questa classe eredita tutto ciò che è public e protected dalla classe Cane +class MioCane : public Cane { - void setOwner(const std::string& dogsOwner) + void impostaProprietario(const std::string& proprietarioCane) - // Override the behavior of the print function for all OwnedDogs. See - // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping - // for a more general introduction if you are unfamiliar with - // subtype polymorphism. - // The override keyword is optional but makes sure you are actually - // overriding the method in a base class. + // Sovrascrivi il comportamento della funzione print per tutti i MioCane. Vedi + // http://it.wikipedia.org/wiki/Polimorfismo_%28informatica%29 + // per una introduzione più generale se non sei familiare con + // il polimorfismo. + // La parola chiave override è opzionale ma fa sì che tu stia effettivamente + // sovrascrivendo il metodo nella classe base. void print() const override; private: - std::string owner; + std::string proprietario; }; -// Meanwhile, in the corresponding .cpp file: +// Nel frattempo, nel file .cpp corrispondente: -void OwnedDog::setOwner(const std::string& dogsOwner) +void MioCane::impostaProprietario(const std::string& proprietarioCane) { - owner = dogsOwner; + proprietario = proprietarioCane; } -void OwnedDog::print() const +void MioCane::print() const { - Dog::print(); // Call the print function in the base Dog class - std::cout << "Dog is owned by " << owner << "\n"; - // Prints "Dog is and weights " - // "Dog is owned by " + Cane::print(); // Chiama la funzione print nella classe base Cane + std::cout << "Il cane è di " << proprietario << "\n"; + // stampa "Il cane è e pesa " + // "Il cane è di " } -////////////////////////////////////////// -// Initialization and Operator Overloading -////////////////////////////////////////// +/////////////////////////////////////////////////// +// Inizializzazione ed Overloading degli Operatori +////////////////////////////////////////////////// -// In C++ you can overload the behavior of operators such as +, -, *, /, etc. -// This is done by defining a function which is called -// whenever the operator is used. +// In C++ puoi sovrascrivere il comportamento di operatori come +, -, *, /, ecc... +// Questo è possibile definendo una funzioneche viene chiamata +// ogniqualvolta l'operatore è usato. #include using namespace std; -class Point { +class Punto { public: - // Member variables can be given default values in this manner. + // Così si assegna alle variabili membro un valore di default. double x = 0; double y = 0; - // Define a default constructor which does nothing - // but initialize the Point to the default value (0, 0) - Point() { }; + // Definisce un costruttore di default che non fa nulla + // ma inizializza il Punto ai valori di default (0, 0) + Punto() { }; - // The following syntax is known as an initialization list - // and is the proper way to initialize class member values - Point (double a, double b) : + // La sintassi seguente è nota come lista di inizializzazione + // ed è il modo appropriato di inizializzare i valori membro della classe + Punto (double a, double b) : x(a), y(b) - { /* Do nothing except initialize the values */ } + { /* Non fa nulla eccetto inizializzare i valori */ } - // Overload the + operator. - Point operator+(const Point& rhs) const; + // Sovrascrivi l'operatore +. + Punto operator+(const Punto& rhs) const; - // Overload the += operator - Point& operator+=(const Point& rhs); + // Sovrascrivi l'operatore += + Punto& operator+=(const Punto& rhs); - // It would also make sense to add the - and -= operators, - // but we will skip those for brevity. + // Avrebbe senso aggiungere gli operatori - e -=, + // ma li saltiamo per rendere la guida più breve. }; -Point Point::operator+(const Point& rhs) const +Punto Punto::operator+(const Punto& rhs) const { - // Create a new point that is the sum of this one and rhs. - return Point(x + rhs.x, y + rhs.y); + // Crea un nuovo punto come somma di questo e di rhs. + return Punto(x + rhs.x, y + rhs.y); } -Point& Point::operator+=(const Point& rhs) +Punto& Punto::operator+=(const Punto& rhs) { x += rhs.x; y += rhs.y; @@ -425,13 +425,13 @@ Point& Point::operator+=(const Point& rhs) } int main () { - Point up (0,1); - Point right (1,0); - // This calls the Point + operator - // Point up calls the + (function) with right as its paramater - Point result = up + right; - // Prints "Result is upright (1,1)" - cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; + Punto su (0,1); + Punto destro (1,0); + // Questo chiama l'operatore + di Punto + // Il Punto su chiama la funzione + con destro come argomento + Punto risultato = su + destro; + // Stampa "Risultato è spostato in (1,1)" + cout << "Risultato è spostato (" << risultato.x << ',' << risultato.y << ")\n"; return 0; } @@ -441,14 +441,14 @@ int main () { // La libreria standard fornisce un paio di tipi d'eccezioni // (vedi http://en.cppreference.com/w/cpp/error/exception) -// ma ogni tipo puo' essere lanciato come eccezione +// ma ogni tipo può essere lanciato come eccezione #include // Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi // handlers _catch_. try { // Non allocare eccezioni nello heap usando _new_. - throw std::exception("E' avvenuto un problema"); + throw std::exception("È avvenuto un problema"); } // Cattura le eccezioni come riferimenti const se sono oggetti catch (const std::exception& ex) @@ -466,8 +466,8 @@ catch (const std::exception& ex) /////// // RAII sta per Resource Allocation Is Initialization. -// Spesso viene considerato come il piu' potente paradigma in C++. -// E' un concetto semplice: un costruttore di un oggetto +// Spesso viene considerato come il più potente paradigma in C++. +// È un concetto semplice: un costruttore di un oggetto // acquisisce le risorse di tale oggetto ed il distruttore le rilascia. // Per comprendere come questo sia vantaggioso, @@ -476,122 +476,122 @@ void faiQualcosaConUnFile(const char* nomefile) { // Per cominciare, assumiamo che niente possa fallire. - FILE* fh = fopen(nomefile, "r"); // Apri il file in modalita' lettura. + FILE* fh = fopen(nomefile, "r"); // Apri il file in modalità lettura. - faiQualcosaConUnFile(fh); + faiQualcosaConIlFile(fh); faiQualcosAltroConEsso(fh); fclose(fh); // Chiudi il gestore di file. } -// Unfortunately, things are quickly complicated by error handling. -// Suppose fopen can fail, and that doSomethingWithTheFile and -// doSomethingElseWithIt return error codes if they fail. -// (Exceptions are the preferred way of handling failure, -// but some programmers, especially those with a C background, -// disagree on the utility of exceptions). -// We now have to check each call for failure and close the file handle -// if a problem occurred. -bool doSomethingWithAFile(const char* filename) +// Sfortunatamente, le cose vengono complicate dalla gestione degli errori. +// Supponiamo che fopen fallisca, e che faiQualcosaConUnFile e +// faiQualcosAltroConEsso ritornano codici d'errore se falliscono. +// (Le eccezioni sono la maniera preferita per gestire i fallimenti, +// ma alcuni programmatori, specialmente quelli con un passato in C, +// non sono d'accordo con l'utilità delle eccezioni). +// Adesso dobbiamo verificare che ogni chiamata per eventuali fallimenti e chiudere il gestore di file +// se un problema è avvenuto. +bool faiQualcosaConUnFile(const char* nomefile) { - FILE* fh = fopen(filename, "r"); // Open the file in read mode - if (fh == nullptr) // The returned pointer is null on failure. - return false; // Report that failure to the caller. - - // Assume each function returns false if it failed - if (!doSomethingWithTheFile(fh)) { - fclose(fh); // Close the file handle so it doesn't leak. - return false; // Propagate the error. + FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura + if (fh == nullptr) // Il puntatore restituito è null in caso di fallimento. + return false; // Riporta il fallimento al chiamante. + + // Assumiamo che ogni funzione ritorni false se ha fallito + if (!faiQualcosaConIlFile(fh)) { + fclose(fh); // Chiude il gestore di file così che non sprechi memoria. + return false; // Propaga l'errore. } - if (!doSomethingElseWithIt(fh)) { - fclose(fh); // Close the file handle so it doesn't leak. - return false; // Propagate the error. + if (!faiQualcosAltroConEsso(fh)) { + fclose(fh); // Chiude il gestore di file così che non sprechi memoria. + return false; // Propaga l'errore. } - fclose(fh); // Close the file handle so it doesn't leak. - return true; // Indicate success + fclose(fh); // Chiudi il gestore di file così che non sprechi memoria. + return true; // Indica successo } -// C programmers often clean this up a little bit using goto: -bool doSomethingWithAFile(const char* filename) +// I programmatori C in genere puliscono questa procedura usando goto: +bool faiQualcosaConUnFile(const char* nomefile) { - FILE* fh = fopen(filename, "r"); + FILE* fh = fopen(nomefile, "r"); if (fh == nullptr) return false; - if (!doSomethingWithTheFile(fh)) - goto failure; + if (!faiQualcosaConIlFile(fh)) + goto fallimento; - if (!doSomethingElseWithIt(fh)) - goto failure; + if (!faiQualcosAltroConEsso(fh)) + goto fallimento; - fclose(fh); // Close the file - return true; // Indicate success + fclose(fh); // Chiude il file + return true; // Indica successo -failure: +fallimento: fclose(fh); - return false; // Propagate the error + return false; // Propaga l'errore } -// If the functions indicate errors using exceptions, -// things are a little cleaner, but still sub-optimal. -void doSomethingWithAFile(const char* filename) +// Se le funzioni indicano errori usando le eccezioni, +// le cose sono un pò più pulite, ma sono sempre sub-ottimali. +void faiQualcosaConUnFile(const char* nomefile) { - FILE* fh = fopen(filename, "r"); // Open the file in read mode + FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura if (fh == nullptr) - throw std::exception("Could not open the file."); + throw std::exception("Non è stato possibile aprire il file."). try { - doSomethingWithTheFile(fh); - doSomethingElseWithIt(fh); + faiQualcosaConIlFile(fh); + faiQualcosAltroConEsso(fh); } catch (...) { - fclose(fh); // Be sure to close the file if an error occurs. - throw; // Then re-throw the exception. + fclose(fh); // Fai sì che il file venga chiuso se si ha un errore. + throw; // Poi rilancia l'eccezione. } - fclose(fh); // Close the file - // Everything succeeded + fclose(fh); // Chiudi il file + // Tutto è andato bene } -// Compare this to the use of C++'s file stream class (fstream) -// fstream uses its destructor to close the file. -// Recall from above that destructors are automatically called -// whenever an object falls out of scope. -void doSomethingWithAFile(const std::string& filename) +// Confronta questo con l'utilizzo della classe C++ file stream (fstream) +// fstream usa i distruttori per chiudere il file. +// Come detto sopra, i distruttori sono automaticamente chiamati +// ogniqualvolta un oggetto esce dalla visibilità. +void faiQualcosaConUnFile(const std::string& nomefile) { - // ifstream is short for input file stream - std::ifstream fh(filename); // Open the file - - // Do things with the file - doSomethingWithTheFile(fh); - doSomethingElseWithIt(fh); - -} // The file is automatically closed here by the destructor - -// This has _massive_ advantages: -// 1. No matter what happens, -// the resource (in this case the file handle) will be cleaned up. -// Once you write the destructor correctly, -// It is _impossible_ to forget to close the handle and leak the resource. -// 2. Note that the code is much cleaner. -// The destructor handles closing the file behind the scenes -// without you having to worry about it. -// 3. The code is exception safe. -// An exception can be thrown anywhere in the function and cleanup -// will still occur. - -// All idiomatic C++ code uses RAII extensively for all resources. -// Additional examples include -// - Memory using unique_ptr and shared_ptr -// - Containers - the standard library linked list, -// vector (i.e. self-resizing array), hash maps, and so on -// all automatically destroy their contents when they fall out of scope. -// - Mutexes using lock_guard and unique_lock + // ifstream è l'abbreviazione di input file stream + std::ifstream fh(nomefile); // Apre il file + + // Fai qualcosa con il file + faiQualcosaConIlFile(fh); + faiQualcosAltroConEsso(fh); + +} // Il file viene chiuso automaticamente chiuso qui dal distruttore + +// Questo ha vantaggi _enormi_: +// 1. Può succedere di tutto ma +// la risorsa (in questo caso il file handler) verrà ripulito. +// Una volta che scrivi il distruttore correttamente, +// È _impossibile_ scordarsi di chiudere l'handler e sprecare memoria. +// 2. Nota che il codice è molto più pulito. +// Il distruttore gestisce la chiusura del file dietro le scene +// senza che tu debba preoccupartene. +// 3. Il codice è sicuro da eccezioni. +// Una eccezione può essere lanciata in qualunque punto nella funzione e la ripulitura +// avverrà lo stesso. + +// Tutto il codice C++ idiomatico usa RAII in maniera vasta su tutte le risorse. +// Esempi aggiuntivi includono +// - Utilizzo della memoria con unique_ptr e shared_ptr +// - I contenitori - la lista della libreria standard, +// vettori (i.e. array auto-aggiustati), mappe hash, e così via +// sono tutti automaticamente distrutti con i loro contenuti quando escono dalla visibilità. +// - I mutex usano lock_guard e unique_lock ``` Letture consigliate: -Un riferimento aggiornato del linguaggio puo' essere trovato qui +Un riferimento aggiornato del linguaggio può essere trovato qui Risorse addizionali possono essere trovate qui -- cgit v1.2.3 From e6900d270be10d1516a8ea32f208bba2d8611e4f Mon Sep 17 00:00:00 2001 From: robertmargelli Date: Sat, 9 May 2015 14:54:19 -0700 Subject: C++ italian is up to date --- it-it/c++-it.html.markdown | 125 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) (limited to 'it-it/c++-it.html.markdown') diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown index 429c976f..39afced5 100644 --- a/it-it/c++-it.html.markdown +++ b/it-it/c++-it.html.markdown @@ -35,7 +35,6 @@ uno dei più utilizzati linguaggi di programmazione. // Proprio come nel C, l'inizio del programma è una funzione chiamata // main con un intero come tipo di ritorno, -// nonostante void main() sia anch'essa accettata dalla maggior parte dei compilatori(gcc, clang, ecc...) // Questo valore serve come stato d'uscita del programma. // Vedi http://it.wikipedia.org/wiki/Valore_di_uscita per maggiori informazioni. int main(int argc, char** argv) @@ -435,6 +434,83 @@ int main () { return 0; } +///////////////// +// Templates +//////////////// + +// Generalmente i templates in C++ sono utilizzati per programmazione generica, anche se +// sono molto più potenti dei costrutti generici in altri linguaggi. Inoltre, +// supportano specializzazione esplicita e parziale, classi in stile funzionale, +// e sono anche complete per Turing. + +// Iniziamo con il tipo di programmazione generica con cui forse sei familiare. Per +// definire una classe o una funzione che prende un parametro di un dato tipo: +template +class Box { + // In questa classe, T può essere usato come qualsiasi tipo. + void inserisci(const T&) { ... } +}; + +// Durante la compilazione, il compilatore in effetti genera copie di ogni template +// con i parametri sostituiti, e così la definizione completa della classe deve essere +// presente ad ogni invocazione. Questo è il motivo per cui vedrai le classi template definite +// interamente in header files. + +// Per instanziare una classe template sullo stack: +Box intBox; + +// e puoi usarla come aspettato: +intBox.inserisci(123); + +//Puoi, ovviamente, innestare i templates: +Box > boxOfBox; +boxOfBox.inserisci(intBox); + +// Fino al C++11, devi porre uno spazio tra le due '>', altrimenti '>>' +// viene visto come l'operatore di shift destro. + +// Qualche volta vedrai +// template +// invece. La parole chiavi 'class' e 'typename' sono _generalmente_ +// intercambiabili in questo caso. Per una spiegazione completa, vedi +// http://en.wikipedia.org/wiki/Typename +// (si, quella parola chiave ha una sua pagina di Wikipedia propria). + +// Similmente, una funzione template: +template +void abbaiaTreVolte(const T& input) +{ + input.abbaia(); + input.abbaia(); + input.abbaia(); +} + +// Nota che niente è specificato relativamente al tipo di parametri. Il compilatore +// genererà e poi verificherà il tipo di ogni invocazione del template, così che +// la funzione di cui sopra funzione con ogni tipo 'T' che ha const 'abbaia' come metodo! + +Cane fluffy; +fluffy.impostaNome("Fluffy") +abbaiaTreVolte(fluffy); // Stampa "Fluffy abbaia tre volte. + +// I parametri template non devono essere classi: +template +void stampaMessaggio() { + cout << "Impara il C++ in " << Y << " minuti!" << endl; +} + +// E poi esplicitamente specializzare i template per avere codice più efficiente. Ovviamente, +// la maggior parte delle casistiche reali non sono così triviali. +// Notare che avrai comunque bisogna di dichiarare la funzione (o classe) come un template +// anche se hai esplicitamente specificato tutti i parametri. +template<> +void stampaMessaggio<10>() { + cout << "Impara il C++ più velocemente in soli 10 minuti!" << endl; +} + +printMessage<20>(); // Stampa "impara il C++ in 20 minuti!" +printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti!" + //////////////////////////// // Gestione delle eccezioni /////////////////////////// @@ -588,6 +664,53 @@ void faiQualcosaConUnFile(const std::string& nomefile) // vettori (i.e. array auto-aggiustati), mappe hash, e così via // sono tutti automaticamente distrutti con i loro contenuti quando escono dalla visibilità. // - I mutex usano lock_guard e unique_lock + +/////////////////////// +// Roba divertente +////////////////////// + +// Aspetti del C++ che potrebbero sbalordire i nuovi arrivati (e anche qualche veterano). +// Questa sezione è, fortunatamente, selvaggiamente incompleta; il C++ è uno dei linguaggi +// più facili con cui puoi spararti da solo nel piede. + +// Puoi sovrascrivere metodi privati! +class Foo { + virtual void bar(); +}; +class FooSub : public Foo { + virtual void bar(); // sovrascrive Foo::bar! +}; + + +// 0 == false == NULL (la maggior parte delle volte)! +bool* pt = new bool; +*pt = 0; // Setta il valore puntato da 'pt' come falso. +pt = 0; // Setta 'pt' al puntatore null. Entrambe le righe vengono compilate senza warnings. + +// nullptr dovrebbe risolvere alcune di quei problemi: +int* pt2 = new int; +*pt2 = nullptr; // Non compila +pt2 = nullptr; // Setta pt2 a null. + +// Ma in qualche modo il tipo 'bool' è una eccezione (questo è per rendere compilabile `if (ptr)`. +*pt = nullptr; // Questo compila, anche se '*pt' è un bool! + + +// '=' != '=' != '='! +// Chiama Foo::Foo(const Foo&) o qualche variante del costruttore di copia. +Foo f2; +Foo f1 = f2; + +// Chiama Foo::Foo(const Foo&) o qualche variante, ma solo copie di 'Foo' che fanno parte di +// 'fooSub'. Ogni altro membro di 'fooSub' viene scartato. Questo comportamento +// orribile viene chiamato "object slicing." +FooSub fooSub; +Foo f1 = fooSub; + +// Chiama Foo::operator=(Foo&) o una sua variante. +Foo f1; +f1 = f2; + ``` Letture consigliate: -- cgit v1.2.3 From 9311ca75afcc2338a03980b800f4f1eaa40bee8c Mon Sep 17 00:00:00 2001 From: robertmargelli Date: Sat, 9 May 2015 19:18:04 -0700 Subject: fixed C++/it typos --- it-it/c++-it.html.markdown | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'it-it/c++-it.html.markdown') diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown index 39afced5..4f5ac8a2 100644 --- a/it-it/c++-it.html.markdown +++ b/it-it/c++-it.html.markdown @@ -42,8 +42,8 @@ int main(int argc, char** argv) // Gli argomenti a linea di comando sono passati tramite argc e argv così come // avviene in C. // argc indica il numero di argomenti, - // e argv è un array in stile-C di stringhe (char*) - // che rappresenta gl iargomenti. + // e argv è un array di stringhe in stile-C (char*) + // che rappresenta gli argomenti. // Il primo argomento è il nome che è stato assegnato al programma. // argc e argv possono essere omessi se non hai bisogno di argomenti, // in questa maniera la funzione avrà int main() come firma. @@ -177,7 +177,7 @@ int main() // cin, cout, e cerr i quali rappresentano stdin, stdout, e stderr. // << è l'operatore di inserzione >> è l'operatore di estrazione. -#include // Include for I/O streams +#include // Include gli streams di I/O using namespace std; // Gli streams sono nel namespace std (libreria standard) @@ -377,7 +377,7 @@ void MioCane::print() const ////////////////////////////////////////////////// // In C++ puoi sovrascrivere il comportamento di operatori come +, -, *, /, ecc... -// Questo è possibile definendo una funzioneche viene chiamata +// Questo è possibile definendo una funzione che viene chiamata // ogniqualvolta l'operatore è usato. #include @@ -491,7 +491,7 @@ void abbaiaTreVolte(const T& input) Cane fluffy; fluffy.impostaNome("Fluffy") -abbaiaTreVolte(fluffy); // Stampa "Fluffy abbaia tre volte. +abbaiaTreVolte(fluffy); // Stampa "Fluffy abbaia" tre volte. // I parametri template non devono essere classi: template @@ -670,7 +670,7 @@ void faiQualcosaConUnFile(const std::string& nomefile) ////////////////////// // Aspetti del C++ che potrebbero sbalordire i nuovi arrivati (e anche qualche veterano). -// Questa sezione è, fortunatamente, selvaggiamente incompleta; il C++ è uno dei linguaggi +// Questa sezione è, sfortunatamente, selvaggiamente incompleta; il C++ è uno dei linguaggi // più facili con cui puoi spararti da solo nel piede. // Puoi sovrascrivere metodi privati! -- cgit v1.2.3 From 68b05bcc518064dab26c5098ea369a71bb9b5d8e Mon Sep 17 00:00:00 2001 From: ven Date: Wed, 17 Jun 2015 23:25:16 +0200 Subject: Fix adambard/learnxinyminutes-site#12 --- it-it/c++-it.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'it-it/c++-it.html.markdown') diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown index 4f5ac8a2..e7e1d89e 100644 --- a/it-it/c++-it.html.markdown +++ b/it-it/c++-it.html.markdown @@ -1,6 +1,6 @@ --- language: c++ -filename: learncpp.cpp +filename: learncpp-it.cpp contributors: - ["Steven Basart", "http://github.com/xksteven"] - ["Matt Kline", "https://github.com/mrkline"] -- cgit v1.2.3 From 35b921505b38ff3686c79826aadde9847e9b2f53 Mon Sep 17 00:00:00 2001 From: Tommaso Date: Sun, 18 Oct 2015 11:42:37 +0200 Subject: [c++/it] Bring this version up to date with the english one The following commits were taken into consideration and translated into italian: 462ac892179d64437b1124263402378a6054e50b 3db1042157204ad05484d6b42140261f849040cc cea52ca43490b74316781c23779654fd46aaeab4 47d3cea47e8c5203efa857070a00dcfbff67b019 894792e1e17173823a5d50de24439427c69d63f4 06889be239622266d9c36c750f7ee755ccdae05d 97b97408eab97fbe322df4266cda9ab2ed21fceb 1d1def16a5d7925bb8f7fba7dc49182e33359e85 a230d76307ecbc0f53c4b359cdb90628720f915e fc9ae44e4887500634bf3a87343d687b4d7d4e3c 85f6ba0b57b9d894c694df66449b1e1c555c625b 8eb410208a8d9b0a42f6c52411455ace04c78101 ae86e4ebabb0c78c1bd8052e6ab5916446ef39c2 455afa3a7bf59fc272f3439825da55659765eec0 12286a4b78f82bde3907d4bf348e20c12dd6d46f 9bc553c46ce9b7154ec7c82451d71608f4beda82 87e8e77e5fd8d84a252dbb6d6697202118378774 3b246fd869564b0a7f7c847f44aecac82d318c78 9d64b532f8ccdfd95c2417dcf65257385956353a e32eb715ef41e411da0a91b40e6e35f150a9c2eb ca435fbb0dd09cdc9c70fe945a891ae3e6c19ab2 --- it-it/c++-it.html.markdown | 211 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 185 insertions(+), 26 deletions(-) (limited to 'it-it/c++-it.html.markdown') diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown index e7e1d89e..92ebc165 100644 --- a/it-it/c++-it.html.markdown +++ b/it-it/c++-it.html.markdown @@ -4,6 +4,8 @@ filename: learncpp-it.cpp contributors: - ["Steven Basart", "http://github.com/xksteven"] - ["Matt Kline", "https://github.com/mrkline"] + - ["Geoff Liu", "http://geoffliu.me"] + - ["Connor Waters", "http://github.com/connorwaters"] translators: - ["Robert Margelli", "http://github.com/sinkswim/"] lang: it-it @@ -54,11 +56,11 @@ int main(int argc, char** argv) // Tuttavia, il C++ varia nei seguenti modi: -// In C++, i caratteri come letterali sono da un byte. -sizeof('c') == 1 +// In C++, i caratteri come letterali sono dei char. +sizeof('c') == sizeof(char) == 1 -// In C, i caratteri come letterali sono della stessa dimensione degli interi. -sizeof('c') == sizeof(10) +// In C, i caratteri come letterali sono degli interi. +sizeof('c') == sizeof(int) // C++ ha prototipizzazione rigida @@ -160,11 +162,14 @@ void foo() int main() { - // Assume che tutto venga dal namespace "Secondo" - // a meno che non venga dichiarato altrimenti. + // Include tutti i simboli del namespace Secondo nello scope attuale. + // Osserva che chiamare semplicemente foo() non va più bene perché è ambiguo: + // bisogna specificare se vogliamo chiamare foo definita nel namespace Secondo + // o foo definita nel livello principale del programma. + using namespace Secondo; - foo(); // stampa "Questa è Secondo::foo" + Secondo::foo(); // stampa "Questa è Secondo::foo" Primo::Annidato::foo(); // stampa "Questa è Primo::Annidato::foo" ::foo(); // stampa "Questa è foo globale" } @@ -244,12 +249,137 @@ cout << fooRef; // Stampa "Io sono foo. Ciao!" // Non riassegna "fooRef". Questo è come scrivere "foo = bar", e // foo == "Io sono bar" // dopo questa riga. +cout << &fooRef << endl; // Stampa l'indirizzo di foo fooRef = bar; +cout << &fooRef << endl; // Stampa lo stesso l'indirizzo di foo +cout << fooRef; // Stampa "Io sono bar" + +// L'indirizzo di fooRef rimane lo stesso, ovvero si riferisce ancora a foo. + const string& barRef = bar; // Crea un riferimento const a bar. // Come in C, i valori const (i puntatori e i riferimenti) non possono essere modificati. barRef += ". Ciao!"; // Errore, i riferimenti const non possono essere modificati. +// Facciamo un piccolo excursus: prima di approfondire ancora i riferimenti, è necessario +// introdurre il concetto di oggetto temporaneo. Supponiamo di avere il seguente codice: +string tempObjectFun() { ... } +string retVal = tempObjectFun(); + +// Nella seconda riga si ha che: +// - un oggetto di tipo stringa viene ritornato da tempObjectFun +// - viene costruita una nuova stringa, utilizzando l'oggetto ritornato come +// argomento per il costruttore +// - l'oggetto ritornato da tempObjectFun viene distrutto +// L'oggetto ritornato da tempObjectFun viene detto oggetto temporaneo. +// Un oggetto temporaneo viene creato quando una funzione ritorna un oggetto, e viene +// distrutto quando l'espressione che lo racchiude termina la sua esecuzione - questo +// comportamento viene definito dallo standard, ma i compilatori possono modificarlo +// a piacere. Cerca su google "return value optimization" se vuoi approfondire. +// Dunque nel seguente codice: +foo(bar(tempObjectFun())) + +// dando per scontato che foo e bar esistano, l'oggetto ritornato da tempObjectFun +// è passato a bar ed è distrutto prima dell'invocazione di foo. + +// Tornando ai riferimenti, c'è un'eccezione a quanto appena detto. +// Infatti un oggetto temporaneo "viene distrutto quando l'espressione +// che lo racchiude termina la sua esecuzione", tranne quando è legato ad un +// riferimento di tipo const. In tal caso la sua vita viene estesa per tutto +// lo scope attuale: + +void constReferenceTempObjectFun() { + // constRef riceve l'oggetto temporaneo, che non viene distrutto fino + // alla fine di questa funzione. + const string& constRef = tempObjectFun(); + ... +} + +// Un altro tipo di riferimento introdotto nel C++11 è specifico per gli +// oggetti temporanei. Non puoi dichiarare una variabile di quel tipo, ma +// ha la precedenza nella risoluzione degli overload: + +void someFun(string& s) { ... } // Riferimento normale +void someFun(string&& s) { ... } // Riferimento ad un oggetto temporaneo + +string foo; +someFun(foo); // Chiama la versione con il riferimento normale +someFun(tempObjectFun()); // Chiama la versione con il riferimento temporaneo + +// Ad esempio potrai vedere questi due costruttori per std::basic_string: +basic_string(const basic_string& other); +basic_string(basic_string&& other); + +// L'idea è che se noi costruiamo una nuova stringa a partire da un oggetto temporaneo +// (che in ogni caso verrà distrutto), possiamo avere un costruttore più efficiente +// che in un certo senso "recupera" parti di quella stringa temporanea. +// Ci si riferisce a questo concetto come "move semantics". + +///////////////////// +// Enum +///////////////////// + +// Gli enum sono un modo per assegnare un valore ad una costante, e sono +// principalmente usati per rendere il codice più leggibile. +enum ETipiMacchine +{ + AlfaRomeo, + Ferrari, + SUV, + Panda +}; + +ETipiMacchine GetPreferredCarType() +{ + return ETipiMacchine::Ferrari; +} + +// Dal C++11 in poi c'è un modo molto semplice per assegnare un tipo ad un enum, +// che può essere utile per la serializzazione dei dati o per convertire gli enum +// tra il tipo desiderato e le rispettive costanti. +enum ETipiMacchine : uint8_t +{ + AlfaRomeo, // 0 + Ferrari, // 1 + SUV = 254, // 254 + Ibrida // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serializza InputValue in un file +} + +void WritePreferredCarTypeToFile(ETipiMacchine InputCarType) +{ + // L'enum viene implicitamente convertito ad un uint8_t poiché + // è stato dichiarato come tale + WriteByteToFile(InputCarType); +} + +// D'altro canto potresti voler evitare che un enum venga accidentalmente convertito +// in un intero o in un altro tipo, quindi è possibile create una classe enum che +// impedisce la conversione implicita. +enum class ETipiMacchine : uint8_t +{ + AlfaRomeo, // 0 + Ferrari, // 1 + SUV = 254, // 254 + Ibrida // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serializza InputValue in un file +} + +void WritePreferredCarTypeToFile(ETipiMacchine InputCarType) +{ + // Il compilatore darà errore anche se ETipiMacchine è un uint8_t: questo + // perchè abbiamo dichiarato l'enum come "enum class"! + WriteByteToFile(InputCarType); +} + ////////////////////////////////////////////////// // Classi e programmazione orientata agli oggetti ///////////////////////////////////////////////// @@ -296,13 +426,16 @@ public: // Questi sono chiamati quando un oggetto è rimosso o esce dalla visibilità. // Questo permette paradigmi potenti come il RAII // (vedi sotto) - // I distruttori devono essere virtual per permettere a classi di essere derivate da questa. + // I distruttori devono essere virtual per permettere a classi di essere + // derivate da questa; altrimenti, il distruttore della classe derivata + // non viene chiamato se l'oggetto viene distrutto tramite un riferimento alla + // classe da cui ha ereditato o tramite un puntatore. virtual ~Dog(); }; // Un punto e virgola deve seguire la definizione della funzione // Le funzioni membro di una classe sono generalmente implementate in files .cpp . -void Cane::Cane() +Cane::Cane() { std::cout << "Un cane è stato costruito\n"; } @@ -325,7 +458,7 @@ void Cane::print() const std::cout << "Il cane è " << nome << " e pesa " << peso << "kg\n"; } -void Cane::~Cane() +Cane::~Cane() { cout << "Ciao ciao " << nome << "\n"; } @@ -340,10 +473,12 @@ int main() { // Ereditarietà: -// Questa classe eredita tutto ciò che è public e protected dalla classe Cane +// Questa classe eredita tutto ciò che è public e protected dalla classe Cane, +// ma anche ciò che privato: tuttavia non potrà accedere direttamente a membri/metodi +// privati se non c'è un metodo pubblico o privato che permetta di farlo. class MioCane : public Cane { - void impostaProprietario(const std::string& proprietarioCane) + void impostaProprietario(const std::string& proprietarioCane); // Sovrascrivi il comportamento della funzione print per tutti i MioCane. Vedi // http://it.wikipedia.org/wiki/Polimorfismo_%28informatica%29 @@ -447,6 +582,7 @@ int main () { // definire una classe o una funzione che prende un parametro di un dato tipo: template class Box { +public: // In questa classe, T può essere usato come qualsiasi tipo. void inserisci(const T&) { ... } }; @@ -519,19 +655,23 @@ printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti // (vedi http://en.cppreference.com/w/cpp/error/exception) // ma ogni tipo può essere lanciato come eccezione #include +#include // Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi // handlers _catch_. try { // Non allocare eccezioni nello heap usando _new_. - throw std::exception("È avvenuto un problema"); + throw std::runtime_error("C'è stato un problema."); } + // Cattura le eccezioni come riferimenti const se sono oggetti catch (const std::exception& ex) { - std::cout << ex.what(); + std::cout << ex.what(); +} + // Cattura ogni eccezioni non catturata dal blocco _catch_ precedente -} catch (...) +catch (...) { std::cout << "Catturata un'eccezione sconosciuta"; throw; // Rilancia l'eccezione @@ -541,7 +681,7 @@ catch (const std::exception& ex) // RAII /////// -// RAII sta per Resource Allocation Is Initialization. +// RAII sta per "Resource Allocation Is Initialization". // Spesso viene considerato come il più potente paradigma in C++. // È un concetto semplice: un costruttore di un oggetto // acquisisce le risorse di tale oggetto ed il distruttore le rilascia. @@ -563,9 +703,9 @@ void faiQualcosaConUnFile(const char* nomefile) // Sfortunatamente, le cose vengono complicate dalla gestione degli errori. // Supponiamo che fopen fallisca, e che faiQualcosaConUnFile e // faiQualcosAltroConEsso ritornano codici d'errore se falliscono. -// (Le eccezioni sono la maniera preferita per gestire i fallimenti, -// ma alcuni programmatori, specialmente quelli con un passato in C, -// non sono d'accordo con l'utilità delle eccezioni). +// (Le eccezioni sono la maniera preferita per gestire i fallimenti, +// ma alcuni programmatori, specialmente quelli con un passato in C, +// non sono d'accordo con l'utilità delle eccezioni). // Adesso dobbiamo verificare che ogni chiamata per eventuali fallimenti e chiudere il gestore di file // se un problema è avvenuto. bool faiQualcosaConUnFile(const char* nomefile) @@ -615,7 +755,7 @@ void faiQualcosaConUnFile(const char* nomefile) { FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura if (fh == nullptr) - throw std::exception("Non è stato possibile aprire il file."). + throw std::runtime_error("Errore nell'apertura del file."); try { faiQualcosaConIlFile(fh); @@ -678,26 +818,29 @@ class Foo { virtual void bar(); }; class FooSub : public Foo { - virtual void bar(); // sovrascrive Foo::bar! + virtual void bar(); // Sovrascrive Foo::bar! }; // 0 == false == NULL (la maggior parte delle volte)! bool* pt = new bool; -*pt = 0; // Setta il valore puntato da 'pt' come falso. +*pt = 0; // Setta il valore puntato da 'pt' come falso. pt = 0; // Setta 'pt' al puntatore null. Entrambe le righe vengono compilate senza warnings. // nullptr dovrebbe risolvere alcune di quei problemi: int* pt2 = new int; -*pt2 = nullptr; // Non compila +*pt2 = nullptr; // Non compila pt2 = nullptr; // Setta pt2 a null. -// Ma in qualche modo il tipo 'bool' è una eccezione (questo è per rendere compilabile `if (ptr)`. -*pt = nullptr; // Questo compila, anche se '*pt' è un bool! +// C'è un'eccezione per i bool. +// Questo permette di testare un puntatore a null con if(!ptr), ma +// come conseguenza non puoi assegnare nullptr a un bool direttamente! +*pt = nullptr; // Questo compila, anche se '*pt' è un bool! // '=' != '=' != '='! -// Chiama Foo::Foo(const Foo&) o qualche variante del costruttore di copia. +// Chiama Foo::Foo(const Foo&) o qualche variante (vedi "move semantics") +// del costruttore di copia. Foo f2; Foo f1 = f2; @@ -711,6 +854,22 @@ Foo f1 = fooSub; Foo f1; f1 = f2; + +// Come deallocare realmente le risorse all'interno di un vettore: +class Foo { ... }; +vector v; +for (int i = 0; i < 10; ++i) + v.push_back(Foo()); + +// La riga seguente riduce la dimensione di v a 0, ma il distruttore non +// viene chiamato e dunque le risorse non sono deallocate! +v.empty(); +v.push_back(Foo()); // Il nuovo valore viene copiato nel primo Foo che abbiamo inserito + +// Distrugge realmente tutti i valori dentro v. Vedi la sezione riguardante gli +// oggetti temporanei per capire come mai funziona così. +v.swap(vector()); + ``` Letture consigliate: -- cgit v1.2.3