1
1
2
2
/*
3
+
4
+
3
5
:: è chiamato operatore di risoluzione dello scope
4
6
l'overloading (sovraccarico) degli operatori (ridefinizione della loro semantica).
5
7
operatori << >> sovraccaricati dalle classi ostream e istream
@@ -18,21 +20,105 @@ Rvalue: valore temporaneo che non esiste più dopo l'espressione che lo usa
18
20
int f(int&& x) {} f(6); OK, rvalue ref
19
21
20
22
int x = 7 + 10; // x Lvalue, (17) Rvalue
23
+
24
+ In C++03, the compiler provides, for classes that do not provide them for themselves, a default constructor,
25
+ a copy constructor, a copy assignment operator (operator=), and a destructor.
26
+
27
+
28
+
29
+
21
30
*/
22
31
#include < iostream> // std:: cin, cout, cerr, endl
23
32
#include < string>
24
33
#include " Alpha.h"
25
34
26
35
using namespace std ; // Rende visibili i nomi definiti in questo namespace
27
36
37
+
38
+ class Collaboratore {
39
+ string m_nome;
40
+ string m_istituto;
41
+ int m_nrcollab;
42
+ public:
43
+ Collaboratore () = default ;
44
+ Collaboratore (string nome, string istituto, int nr_collab) :
45
+ m_nome{nome}, m_istituto{istituto}, m_nrcollab{nr_collab}
46
+ {
47
+ cout << " Collaboratore Ctor" << endl;
48
+ }
49
+
50
+
51
+ string nome () const { return m_nome; }
52
+ string istituto () const { return m_istituto; }
53
+ int nrcollab () const { return m_nrcollab; }
54
+ string nomeclasse () const { return " Collaboratore" ; }
55
+ // virtual string toString()=0; // abstract class
56
+ virtual string toString () { return nome () + " , " + istituto (); }
57
+ };
58
+
59
+ class Docente : public virtual Collaboratore {
60
+ string m_corso;
61
+ public:
62
+ Docente (string nome, string istituto, int nr_collab, string corso) :
63
+ Collaboratore{nome, istituto, nr_collab},
64
+ m_corso{corso}
65
+ {}
66
+ string corso () const { return m_corso;}
67
+ string nomeclasse () const { return " Docente" ; }
68
+
69
+ string toString () override // il compilatore controlla che esista un metodo virtual
70
+ { return nomeclasse () + " : " + corso (); }
71
+ };
72
+
73
+
74
+ class Ricercatore : public virtual Collaboratore {
75
+ string m_arearicerca;
76
+ public:
77
+ Ricercatore (string nome, string istituto, int nr_collab, string arearicerca) :
78
+ Collaboratore{nome, istituto, nr_collab},
79
+ m_arearicerca{arearicerca}
80
+ {}
81
+ string arearicerca () const {return m_arearicerca; }
82
+ string nomeclasse () const { return " Ricercatore" ; }
83
+ };
84
+
85
+ // ereditarieta' multipla: uso virtual base class
86
+ // ora il compilatore usa costruttore vuoto di Collaboratore
87
+ // invece di quello usato nella init-list di Docente e Ricercatore.
88
+ // Quindi il costruttore vuoto va dichiarato esplicito
89
+ // il costruttore con parametri va richiamato esplicitamente in
90
+ // DocenteRicercatore
91
+ class DocenteRicercatore : public Docente , public Ricercatore {
92
+ double m_percRicerca;
93
+ public:
94
+ DocenteRicercatore (string nome, string istituto,
95
+ int nr_collab, string corso, string arearicerca,
96
+ double percRicerca) :
97
+ Collaboratore (nome, istituto, nr_collab),
98
+ Docente{nome, istituto, nr_collab, corso},
99
+ Ricercatore{nome, istituto, nr_collab, arearicerca},
100
+ m_percRicerca{percRicerca}
101
+ {}
102
+ double percRicerca () const { return m_percRicerca; }
103
+ string nomeclasse () const { return " DocenteRicercatore" ; }
104
+ };
105
+
106
+
28
107
enum class Sesso { Maschio, Femmina }; // strongly typed, non convertito in num
29
108
struct Persona { string nome; }; // typedef non necessario
30
109
31
- int moltiplica (int a, int b) { return a*b; }
32
- namespace supsi { namespace dti {
33
- int moltiplica (int a, int b) {
34
- return ::moltiplica (a, b);
35
- }
110
+ void testCast ();
111
+
112
+ void testAuto ();
113
+
114
+ void ordineCostrDestr ();
115
+
116
+ void binding ();
117
+
118
+ int moltiplica (int a, int b) noexcept { return a * b; }
119
+ namespace supsi {
120
+ namespace dti {
121
+ int moltiplica (int a, int b) { return ::moltiplica (a, b); }
36
122
}}
37
123
38
124
void swap (int & x, int & y) {
@@ -41,30 +127,99 @@ void swap(int& x, int& y) {
41
127
y = temp;
42
128
}
43
129
130
+ /*
44
131
int& sbagliato(int& x, int& y) {
45
132
int temp;
46
133
return temp; // Attenzione! Ritorno un rif. a una variabile locale!!!!
47
- }
134
+ }*/
48
135
49
136
namespace xyz = supsi::dti; // alias namespace
50
137
138
+ struct A {
139
+ A () { cout << " create A" << endl; }
140
+ ~A () { cout << " destr A" << endl; }
141
+ string foo () { return " A.foo() " ; }
142
+ // VISIBILITA:
143
+ // Un metodo con lo stesso nome di un metodo di una classe
144
+ // base nasconde tutte le funzioni sovraccaricate con lo stesso
145
+ // nome nella classe base
146
+ string p (int v) { return " A.p(int) " ; }
147
+ string p () { return " A.p() " ; }
148
+
149
+ virtual string f () { return " A.f() " ; }
150
+ };
151
+ struct B : A {
152
+ B () { cout << " create B" << endl; }
153
+ ~B () { cout << " destr B" << endl; }
154
+
155
+ string p (string f) { return " B.p(str) " ; }
156
+
157
+ string foo () { return " B.foo() " ; }
158
+ string f () { return " B.f() " ; }
159
+ };
160
+
51
161
52
162
int main () {
53
- std::cout << xyz::moltiplica (3 ,2 ) << std::endl;
163
+ binding ();
164
+
165
+ // ordineCostrDestr();
166
+ // testAuto();
167
+ // testCast();
168
+ }
169
+
170
+ void binding () {
171
+ // statico: compile time, non permette polimorfismo. ma piu' efficiente
172
+ // polimorfismo: capacita' di scegliere il metodo giusto in base oggetto
173
+ // dinamico: late run time, richiede uso di virtual (default in Java)
174
+ // vtable all'interno della classe (condivisa tra tutti gli oggetti)
175
+ A a; B b;
176
+ A& ab{b};
177
+ cout << " a " << a.foo () << a.f () << a.p () << a.p (12 ) << endl;
178
+ // HIDING: b.p() e b.(12) non disponibili
179
+ cout << " b " << b.foo () << b.f () << b.A ::f () << b.A ::p () << b.A ::p (12 ) << b.p (" c" ) << endl;
180
+ cout << " ab " << ab.foo () << ab.f () << endl;
181
+ }
182
+
183
+ void ordineCostrDestr () {
184
+ // A <- B <- C
185
+ // DERIVAZIONE: protected: i metodi public diventano protected, protected rimangono protected
186
+ // quando istanzio un oggetto di tipo B prima di tutto creo un oggetto A
187
+ // se nella init-list non chiamo esplicitamente un ctor di A, viene cercato il default cto()
188
+ // se non esiste non compila. I ctor classi basi sono chiamati prima di ctor derivate
189
+
190
+ // ## A a
191
+ // create A
192
+ // ## B b
193
+ // create A
194
+ // create B
195
+ // ## end scope
196
+ // destr B
197
+ // destr A
198
+ // destr A
199
+
200
+ cout << " ## A a" << endl;
201
+ A a;
202
+ cout << " ## B b" << endl;
203
+ B b;
204
+ cout << " ## end scope" << endl;
205
+ }
206
+
207
+ void testAuto () {
208
+ cout << supsi::dti::moltiplica (3 , 2 ) << endl;
54
209
string msg{" Ciao mondo!" };
55
210
// string str('x'); // Errore
56
- cout << msg << endl << msg.length () << endl << msg.empty () << endl;
57
- string mystr{" ciao" };
58
- if (mystr == msg) {
59
- cout << mystr[3 ]; // Accesso ai caratteri
60
- }
61
- mystr.insert (5 , " grande" ); // Inserimento di stringhe in stringhe
62
- cout << mystr.substr (1 ,3 );
63
- mystr.erase (3 ,6 );
64
- mystr.replace (0 , 5 , " Hello" );
65
- size_t pos = mystr.find (" mondo" , 0 );
211
+ // cout << msg << endl << msg.length() << endl << msg.empty() << endl;
212
+ // string mystr{"ciao"};
213
+ // if (mystr == msg) {
214
+ // cout << mystr[3]; // Accesso ai caratteri
215
+ // }
216
+ // mystr.insert(5, "grande"); // Inserimento di stringhe in stringhe
217
+ // cout << mystr.substr(1,3);
218
+ // mystr.erase(3,6);
219
+ // mystr.replace(0, 5, "Hello");
220
+ // size_t pos = mystr.find("mondo", 0);
66
221
int pi_a = 3.14 ; // Diventa 3!
67
- int pi_b {3.14 }; // Problema!
222
+ // int pi_b {3.14}; // Problema!
68
223
auto r{1.2 }; // compilatore cambia auto in double
69
224
auto k{moltiplica (4 ,2 )}; // compilatore cambia auto in int
70
225
@@ -80,15 +235,80 @@ int main() {
80
235
delete[] p1;
81
236
int * ip{nullptr };
82
237
238
+ auto lamda = [](int par) -> void { cout << par << endl ; };
239
+
83
240
// oggetto stack distrutto:
84
- // Namespace scope: quando termina il programma
85
- // Class scope: quando l'istanza della classe viene distrutta
241
+ // Namespace scope: quando termina il programma
242
+ // Class scope: quando l'istanza della classe viene distrutta
86
243
87
244
// Riferimento a un intero (alias per a)
88
- // A differenza di un puntatore, un riferimento non
89
- // può essere modificato per “puntare” a qualcos'altro (e magari a niente!)
245
+ // A differenza di un puntatore, un riferimento non
246
+ // può essere modificato per “puntare” a qualcos'altro (e magari a niente!)
90
247
int & c{pi_a}; //
91
248
92
249
// modificare un array
93
250
for (auto & i : mioarray) i++;
94
251
}
252
+
253
+ void testCast () {
254
+ DocenteRicercatore dr{" Massimo" , " SUPSI" , 123 , " DTI" , " MED" , 12.3 };
255
+ cout << dr.nome () << endl;
256
+ cout << typeid (dr).name () << endl; // 18DocenteRicercatore
257
+
258
+ Docente doc{" Giovanni" , " ISIN" , 42 , " Linguaggi e framework" };
259
+ cout << typeid (doc).name () << endl; // 7Docente
260
+
261
+ // static_cast<tipo>(oggetto), check durante compilazione
262
+ // puntatori, riferimenti, oggettti. NO se: base (virtual) -> derivata
263
+ // conversione di oggetto
264
+ Collaboratore coll = static_cast <Collaboratore>(doc);
265
+ cout << typeid (coll).name () << endl; // 13Collaboratore
266
+
267
+ // rif/puntatore
268
+ Collaboratore& rc = static_cast <Collaboratore&>(doc);
269
+ Collaboratore& drc = dynamic_cast <Collaboratore&>(doc);
270
+ cout << typeid (rc).name () << endl; // 13Collaboratore
271
+ cout << " D " << typeid (drc).name () << endl; // D 13Collaboratore
272
+
273
+ Collaboratore* pc = static_cast <Collaboratore*>(&doc);
274
+ Collaboratore* dpc = dynamic_cast <Collaboratore*>(&doc);
275
+ Collaboratore* pd = &doc;
276
+ cout << typeid (pc).name () << endl; // P 13Collaboratore
277
+ cout << " D " << typeid (dpc).name () << endl; // D P13Collaboratore
278
+ cout << " N " << typeid (pd).name () << endl; // M P13Collaboratore
279
+
280
+ // errore non rilevato !!!
281
+ DocenteRicercatore* pdr = static_cast <DocenteRicercatore*>(&doc);
282
+ cout << pdr->percRicerca () << endl; // Spazzatura
283
+ cout << typeid (pdr).name () << endl; //
284
+
285
+ // dynamic_cast<tipo>(punt_o_rif)
286
+ // Effettua una conversione verificando, a compilazione e a runtime
287
+ // upcasting e downcasting (solo se oggetti base hanno almeno un virtual)
288
+ // no void* to Classe*
289
+
290
+ // se non riesce ad effettuare il cast:
291
+ // - puntatore: ritorna un puntatore a 0
292
+ // - riferimento: lancia l'eccezione std::bad_cast
293
+
294
+ // reinterpret_cast<tipo>(puntatore_o_rif);
295
+ // non fa nessun controllo sul contenuto, casta e basta.
296
+
297
+ // const_cast<tipo>(puntatore_o_rif)
298
+ // per eliminare l'attributo const
299
+ // const Base* b{new Base};
300
+ // b->bar(); // Errore! Non è const!
301
+
302
+ // Base* bc = static_cast<Base*>(b); // Non permesso
303
+ // Base* bc = reintepret_cast<Base*>(b); // Non permesso
304
+ // Base* bc = dynamic_cast<Base*>(b); // Non permesso
305
+ // Base* bc = const_cast<Base*>(b); // Ok
306
+ // bc->bar(); // Ok
307
+
308
+ // operatore typeid permette di determinare la classe di
309
+ // un oggetto a runtime
310
+
311
+
312
+
313
+ }
314
+
0 commit comments